[gvfs] gvfschannel: do not crash when channel is blocked



commit 3abf2f64900c8dfb033af748c0aadc0cf61523c5
Author: Ondrej Holy <oholy redhat com>
Date:   Wed Oct 8 16:14:39 2014 +0200

    gvfschannel: do not crash when channel is blocked
    
    Backend could crash, when channel is blocked and got new request
    unless current job is set. Therefor send_reply_cb is called
    without current job and cause following error:
    
    Program received signal SIGSEGV, Segmentation fault.
    0x00007ffff7de12a5 in g_vfs_job_emit_finished (job=0x0) at gvfsjob.c:322
    322      g_assert (!job->finished);
    
    To fix the problem be sure error job is set.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=737842

 daemon/gvfschannel.c |   38 ++++++++++++++++----------------------
 1 files changed, 16 insertions(+), 22 deletions(-)
---
diff --git a/daemon/gvfschannel.c b/daemon/gvfschannel.c
index 994b5ea..88303d0 100644
--- a/daemon/gvfschannel.c
+++ b/daemon/gvfschannel.c
@@ -315,12 +315,22 @@ start_queued_request (GVfsChannel *channel)
                            channel->priv->queued_requests);
 
       error = NULL;
-      /* This passes on ownership of req->data */
-      job = class->handle_request (channel,
-                                  req->command, req->seq_nr,
-                                  req->arg1, req->arg2,
-                                  req->data, req->data_len,
-                                  &error);
+      if (!g_vfs_backend_get_block_requests (channel->priv->backend))
+        {
+         /* This passes on ownership of req->data */
+         job = class->handle_request (channel,
+                                      req->command, req->seq_nr,
+                                      req->arg1, req->arg2,
+                                      req->data, req->data_len,
+                                      &error);
+        }
+      else
+       {
+         job = NULL;
+         error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CLOSED,
+                                      _("Channel blocked"));
+         g_free (req->data);
+       }
 
       if (job != NULL && req->cancelled)
        {
@@ -360,22 +370,6 @@ got_request (GVfsChannel *channel,
   guint32 command, arg1;
   GList *l;
 
-  if (g_vfs_backend_get_block_requests (channel->priv->backend))
-    {
-      char   *data;
-      gsize   data_len;
-      GError *err = NULL;
-      guint32 seq_nr;
-
-      g_set_error_literal (&err, G_IO_ERROR, G_IO_ERROR_CLOSED,
-                          "Channel blocked");
-      seq_nr = g_ntohl (request->seq_nr);
-      data = g_error_to_daemon_reply (err, seq_nr, &data_len);
-      g_vfs_channel_send_reply (channel, NULL, data, data_len);
-      g_error_free (err);
-      return;
-    }
-
   command = g_ntohl (request->command);
   arg1 = g_ntohl (request->arg1);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]