]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Prevent parent loops in mailbox list index
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 15 Nov 2016 23:04:18 +0000 (01:04 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 18 Nov 2016 11:45:37 +0000 (13:45 +0200)
src/lib-storage/list/mailbox-list-index.c

index fcf2cd13f0890b470e9b50a5a7bb8e190108b333..bd848668a73d95cbb20f3653778d24715eff163c 100644 (file)
@@ -254,6 +254,18 @@ mailbox_list_index_node_hash(const struct mailbox_list_index_node *node)
                POINTER_CAST_TO(node->parent, unsigned int);
 }
 
+static bool node_has_parent(const struct mailbox_list_index_node *parent,
+                           const struct mailbox_list_index_node *node)
+{
+       const struct mailbox_list_index_node *n;
+
+       for (n = parent; n != NULL; n = n->parent) {
+               if (n == node)
+                       return TRUE;
+       }
+       return FALSE;
+}
+
 static int mailbox_list_index_parse_records(struct mailbox_list_index *ilist,
                                            struct mail_index_view *view,
                                            const char **error_r)
@@ -329,6 +341,14 @@ static int mailbox_list_index_parse_records(struct mailbox_list_index *ilist,
                                        break;
                                /* just place it under the root */
                                node->corrupted_parent = TRUE;
+                       } else if (node_has_parent(parent, node)) {
+                               *error_r = t_strdup_printf(
+                                       "parent_uid=%u loops to node itself (%s)",
+                                       uid, node->name);
+                               if (ilist->has_backing_store)
+                                       break;
+                               /* just place it under the root */
+                               node->corrupted_parent = TRUE;
                        } else {
                                node->parent = parent;
                                node->next = parent->children;