[evolution-data-server] Fix possible use-after-free in CamelVeeFolder with parent_vee_store



commit 34816303f0bd0d61b78f2c2b0a5ab5a4fb43333f
Author: Milan Crha <mcrha redhat com>
Date:   Wed Dec 7 21:54:48 2016 +0100

    Fix possible use-after-free in CamelVeeFolder with parent_vee_store
    
    Spot on the Evolution quit, when (sometimes) the parent_vee_store
    was freed before the folder, then the priv structure member had been
    left set to a freed pointer (though the CamelFolder's parent_store
    had been nullified properly). Rather than adding more calls around
    getting to the parent_vee_store, make it a weak pointer.

 src/camel/camel-vee-folder.c |   14 ++++++++++----
 1 files changed, 10 insertions(+), 4 deletions(-)
---
diff --git a/src/camel/camel-vee-folder.c b/src/camel/camel-vee-folder.c
index 5e6937f..bdf1578 100644
--- a/src/camel/camel-vee-folder.c
+++ b/src/camel/camel-vee-folder.c
@@ -66,7 +66,7 @@ struct _CamelVeeFolderPrivate {
 
        /* only set-up if our parent is a vee-store, used also as a flag to
         * say that this folder is part of the unmatched folder */
-       CamelVeeStore *parent_vee_store;
+       gpointer parent_vee_store; /* CamelVeeStore *, weak pointer */
 
        CamelVeeDataCache *vee_data_cache;
 };
@@ -553,15 +553,14 @@ subfolder_deleted (CamelFolder *subfolder,
 static void
 vee_folder_dispose (GObject *object)
 {
+       CamelVeeFolder *vfolder;
        CamelFolder *folder;
 
        folder = CAMEL_FOLDER (object);
+       vfolder = CAMEL_VEE_FOLDER (object);
 
        /* parent's class frees summary on dispose, thus depend on it */
        if (camel_folder_get_folder_summary (folder)) {
-               CamelVeeFolder *vfolder;
-
-               vfolder = CAMEL_VEE_FOLDER (object);
                vfolder->priv->destroyed = TRUE;
 
                camel_folder_freeze ((CamelFolder *) vfolder);
@@ -572,6 +571,11 @@ vee_folder_dispose (GObject *object)
                camel_folder_thaw ((CamelFolder *) vfolder);
        }
 
+       if (vfolder->priv->parent_vee_store) {
+               g_object_remove_weak_pointer (G_OBJECT (vfolder->priv->parent_vee_store), 
&vfolder->priv->parent_vee_store);
+               vfolder->priv->parent_vee_store = NULL;
+       }
+
        /* Chain up to parent's dispose () method. */
        G_OBJECT_CLASS (camel_vee_folder_parent_class)->dispose (object);
 }
@@ -1289,6 +1293,8 @@ camel_vee_folder_construct (CamelVeeFolder *vf,
                const gchar *user_data_dir;
                gchar *state_file, *folder_name, *filename;
 
+               g_object_add_weak_pointer (G_OBJECT (vf->priv->parent_vee_store), 
&vf->priv->parent_vee_store);
+
                user_data_dir = camel_service_get_user_data_dir (CAMEL_SERVICE (parent_store));
 
                folder_name = g_uri_escape_string (camel_folder_get_full_name (folder), NULL, TRUE);


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