]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dict-file: Fix potential crash when doing other dict calls during iteration.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 16 Jan 2017 14:58:31 +0000 (16:58 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 17 Jan 2017 12:09:24 +0000 (14:09 +0200)
If file was refreshed, the hash table was cleared, which broke the existing
iterators.

src/lib-dict/dict-file.c

index 1c1357f043cd3d6fb7ae4066c76c804a6cb4076a..76f3562a10e45d2fc7dc33be8d35bbe4f5e05b3f 100644 (file)
@@ -110,6 +110,12 @@ static bool file_dict_need_refresh(struct file_dict *dict)
 {
        struct stat st1, st2;
 
+       if (dict->dict.iter_count > 0) {
+               /* Change nothing while there are iterators or they can crash
+                  because the hash table content recreated. */
+               return FALSE;
+       }
+
        if (dict->fd == -1)
                return TRUE;
 
@@ -171,7 +177,7 @@ static int file_dict_refresh(struct file_dict *dict)
 
        if (file_dict_open_latest(dict) < 0)
                return -1;
-       if (dict->refreshed)
+       if (dict->refreshed || dict->dict.iter_count > 0)
                return 0;
 
        hash_table_clear(dict->hash, TRUE);
@@ -229,10 +235,11 @@ file_dict_iterate_init(struct dict *_dict, const char *const *paths,
                ctx->paths[i].len = strlen(paths[i]);
        }
        ctx->flags = flags;
-       ctx->iter = hash_table_iterate_init(dict->hash);
 
        if (file_dict_refresh(dict) < 0)
                ctx->failed = TRUE;
+
+       ctx->iter = hash_table_iterate_init(dict->hash);
        return &ctx->ctx;
 }