]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
mail_index_atomic_inc_ext(): Added error checking.
authorTimo Sirainen <tss@iki.fi>
Fri, 6 Mar 2009 21:17:39 +0000 (16:17 -0500)
committerTimo Sirainen <tss@iki.fi>
Fri, 6 Mar 2009 21:17:39 +0000 (16:17 -0500)
--HG--
branch : HEAD

src/lib-index/mail-index-sync-ext.c
src/lib-index/mail-index-transaction.c

index 57d18222fbd09bde89d1b431c64a8b0c58d1f572..8ebb074cec51284fe76945fcd52701e64d4d0c71 100644 (file)
@@ -696,6 +696,7 @@ mail_index_sync_ext_atomic_inc(struct mail_index_sync_map_ctx *ctx,
        const struct mail_index_ext *ext;
        void *data;
        uint32_t seq;
+       uint64_t orig_num;
 
        i_assert(ctx->cur_ext_map_idx != (uint32_t)-1);
        i_assert(!ctx->cur_ext_ignore);
@@ -719,21 +720,26 @@ mail_index_sync_ext_atomic_inc(struct mail_index_sync_map_ctx *ctx,
        switch (ext->record_size) {
        case 1: {
                uint8_t *num = data;
+
+               orig_num = *num;
                *num += u->diff;
                break;
        }
        case 2: {
                uint16_t *num = data;
+               orig_num = *num;
                *num += u->diff;
                break;
        }
        case 4: {
                uint32_t *num = data;
+               orig_num = *num;
                *num += u->diff;
                break;
        }
        case 8: {
                uint64_t *num = data;
+               orig_num = *num;
                *num += u->diff;
                break;
        }
@@ -743,6 +749,14 @@ mail_index_sync_ext_atomic_inc(struct mail_index_sync_map_ctx *ctx,
                        ext->record_size);
                return -1;
        }
+       if (u->diff < 0 && (uint32_t)(-u->diff) > orig_num) {
+               mail_index_sync_set_corrupted(ctx,
+                       "Extension record inc drops number below zero "
+                       "(uid=%u, diff=%d, orig=%llu)",
+                       u->uid, u->diff, (unsigned long long)orig_num);
+               return -1;
+       }
+
        mail_index_sync_write_seq_update(ctx, seq, seq);
        return 1;
 }
index 1f349ab3e980f51958a47dc301f12dbc68cdfc9e..3d8a2d67c4ba9bbf8119f8def6f8c6d22754d532 100644 (file)
@@ -1357,6 +1357,9 @@ void mail_index_atomic_inc_ext(struct mail_index_transaction *t, uint32_t seq,
                 (seq <= mail_index_view_get_messages_count(t->view) ||
                  seq <= t->last_new_seq));
        i_assert(ext_id < array_count(&t->view->index->extensions));
+       /* currently non-external transactions can be applied multiple times,
+          causing multiple increments. */
+       i_assert((t->flags & MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL) != 0);
 
        t->log_ext_updates = TRUE;
        if (!array_is_created(&t->ext_rec_atomics))