[evolution-data-server/gnome-3-22] Fix possible use-after-free in CamelVeeFolder with parent_vee_store



commit c2abee5bf263de4aec418f1ad0bc49b88b3a7e83
Author: Milan Crha <mcrha redhat com>
Date:   Wed Dec 7 22:02:51 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.

 camel/camel-vee-folder.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)
---
diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c
index 5566caa..e836018 100644
--- a/camel/camel-vee-folder.c
+++ b/camel/camel-vee-folder.c
@@ -67,7 +67,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;
 };
@@ -555,14 +555,14 @@ static void
 vee_folder_dispose (GObject *object)
 {
        CamelFolder *folder;
+       CamelVeeFolder *vfolder;
 
        folder = CAMEL_FOLDER (object);
+       vfolder = CAMEL_VEE_FOLDER (object);
 
        /* parent's class frees summary on dispose, thus depend on it */
        if (folder->summary) {
-               CamelVeeFolder *vfolder;
 
-               vfolder = CAMEL_VEE_FOLDER (object);
                vfolder->priv->destroyed = TRUE;
 
                camel_folder_freeze ((CamelFolder *) vfolder);
@@ -573,6 +573,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);
 }
@@ -1277,6 +1282,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]