]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: LAYOUT=index: Fix accessing freed memory when deleting \Noselect parents
authorMarkus Valentin <markus.valentin@open-xchange.com>
Thu, 27 Jan 2022 20:40:25 +0000 (21:40 +0100)
committerMarkus Valentin <markus.valentin@open-xchange.com>
Fri, 28 Jan 2022 07:13:03 +0000 (08:13 +0100)
Broken by f5328d6f7e4a8e460c736fa0336f5766aa58abda

src/lib-storage/list/mailbox-list-index-backend.c

index 4b866980dc7bf734b81da221a9186b88a52d3a25..8abfe44d30d5df87e6a606a109aecde61bbcd2a5 100644 (file)
@@ -696,7 +696,7 @@ index_list_try_delete_nonexistent_parent(struct mailbox_list *_list,
 {
        struct index_mailbox_list *list =
                container_of(_list, struct index_mailbox_list, list);
-       struct mailbox_list_index_node *node, *parent = NULL;
+       struct mailbox_list_index_node *node;
        string_t *full_name;
        const char *p;
        char sep = mailbox_list_get_hierarchy_sep(_list);
@@ -722,14 +722,22 @@ index_list_try_delete_nonexistent_parent(struct mailbox_list *_list,
                           existant or not selectable, delete it */
                        str_truncate(full_name, 0);
                        mailbox_list_index_node_get_path(node, sep, full_name);
-                       parent = node->parent;
                        if (index_list_delete_entry(list, str_c(full_name), FALSE) < 0)
                                return -1;
+
+                       if ((p = strrchr(str_c(full_name), sep)) == NULL) {
+                               /* No occurrences of the hierarchy separator
+                                  could be found in the mailbox that was
+                                  just deleted. */
+                               node = NULL;
+                       } else {
+                               /* lookup parent node of the node just deleted */
+                               str_truncate(full_name, p - str_c(full_name));
+                               node = mailbox_list_index_lookup(_list, str_c(full_name));
+                       }
                } else
                        break;
 
-               /* If there is another parent attempt to delete it as well */
-               node = parent;
        }
        return 0;
 }