[gvfs] sftp: Fix crashes when data connection setup failed



commit 46487b40479c0a422a2a5061bfa8da138a4dc107
Author: Ondrej Holy <oholy redhat com>
Date:   Thu Aug 6 10:13:15 2015 +0200

    sftp: Fix crashes when data connection setup failed
    
    destroy_connection() is called twice when setup of data connection failed.
    Consequently g_hash_table_destroy() is called on already destroyed hash
    table on finalize. Set conn->expected_replies to NULL in destroy_connection()
    to fix the issue.
    
    There is another crash on force unmount when setup of data connection failed.
    fail_jobs() is called on already destroyed connection. Check usability of
    the connection before use to avoid the crash.
    
    Finally move the hast table initialization into the setup_connection,
    because the initialization in g_vfs_backend_sftp_init() is confusing.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=753311

 daemon/gvfsbackendsftp.c |   19 ++++++++++---------
 1 files changed, 10 insertions(+), 9 deletions(-)
---
diff --git a/daemon/gvfsbackendsftp.c b/daemon/gvfsbackendsftp.c
index 1411cea..ae0c363 100644
--- a/daemon/gvfsbackendsftp.c
+++ b/daemon/gvfsbackendsftp.c
@@ -278,7 +278,11 @@ has_extension (GVfsBackendSftp *backend, SFTPServerExtensions extension)
 static void
 destroy_connection (Connection *conn)
 {
-  g_hash_table_destroy (conn->expected_replies);
+  if (conn->expected_replies)
+    {
+      g_hash_table_destroy (conn->expected_replies);
+      conn->expected_replies = NULL;
+    }
 
   g_clear_object (&conn->command_stream);
   g_clear_object (&conn->reply_stream_cancellable);
@@ -315,14 +319,6 @@ expected_reply_free (ExpectedReply *reply)
 static void
 g_vfs_backend_sftp_init (GVfsBackendSftp *backend)
 {
-  backend->command_connection.expected_replies = g_hash_table_new_full (NULL,
-                                                                        NULL,
-                                                                        NULL,
-                                                                        (GDestroyNotify)expected_reply_free);
-  backend->data_connection.expected_replies = g_hash_table_new_full (NULL,
-                                                                     NULL,
-                                                                     NULL,
-                                                                     (GDestroyNotify)expected_reply_free);
 }
 
 static void
@@ -1320,6 +1316,9 @@ fail_jobs (Connection *conn, GError *error)
   GHashTableIter iter;
   gpointer key, value;
 
+  if (!connection_is_usable (conn))
+    return;
+
   g_hash_table_iter_init (&iter, conn->expected_replies);
   while (g_hash_table_iter_next (&iter, &key, &value))
     {
@@ -1812,6 +1811,8 @@ setup_connection (GVfsBackend *backend,
 
   connection->op_backend = op_backend;
   connection->command_stream = g_unix_output_stream_new (stdin_fd, TRUE);
+  connection->expected_replies = g_hash_table_new_full (NULL, NULL, NULL,
+                                                        (GDestroyNotify)expected_reply_free);
 
   command = new_command_stream (op_backend, SSH_FXP_INIT);
   g_data_output_stream_put_int32 (command,


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