dovecot-2.2: doveadm dump: Avoid crashes with corrupted log files
dovecot at dovecot.org
dovecot at dovecot.org
Mon Jun 16 13:27:34 UTC 2014
details: http://hg.dovecot.org/dovecot-2.2/rev/d6882dfa08d7
changeset: 17499:d6882dfa08d7
user: Timo Sirainen <tss at iki.fi>
date: Mon Jun 16 16:26:09 2014 +0300
description:
doveadm dump: Avoid crashes with corrupted log files
diffstat:
src/doveadm/doveadm-dump-log.c | 38 +++++++++++++++++++++++++++++---------
1 files changed, 29 insertions(+), 9 deletions(-)
diffs (94 lines):
diff -r b2e16f0e88db -r d6882dfa08d7 src/doveadm/doveadm-dump-log.c
--- a/src/doveadm/doveadm-dump-log.c Mon Jun 16 15:47:12 2014 +0300
+++ b/src/doveadm/doveadm-dump-log.c Mon Jun 16 16:26:09 2014 +0300
@@ -214,12 +214,18 @@
HDRF(day_stamp)
};
-static void log_header_update(const struct mail_transaction_header_update *u)
+static void log_header_update(const struct mail_transaction_header_update *u,
+ size_t data_size)
{
const void *data = u + 1;
unsigned int offset = u->offset, size = u->size;
unsigned int i;
+ if (sizeof(*u) + size > data_size) {
+ printf(" - offset = %u, size = %u (too large)\n", offset, size);
+ return;
+ }
+
while (size > 0) {
/* don't bother trying to handle header updates that include
unknown/unexpected fields offsets/sizes */
@@ -247,7 +253,8 @@
}
static void log_record_print(const struct mail_transaction_header *hdr,
- const void *data, uint64_t *modseq)
+ const void *data, size_t data_size,
+ uint64_t *modseq)
{
unsigned int size = hdr->size - sizeof(*hdr);
@@ -297,7 +304,7 @@
case MAIL_TRANSACTION_HEADER_UPDATE: {
const struct mail_transaction_header_update *u = data;
- log_header_update(u);
+ log_header_update(u, data_size);
break;
}
case MAIL_TRANSACTION_EXT_INTRO: {
@@ -331,16 +338,26 @@
case MAIL_TRANSACTION_EXT_HDR_UPDATE: {
const struct mail_transaction_ext_hdr_update *u = data;
- printf(" - offset = %u, size = %u: ", u->offset, u->size);
- print_data(u + 1, u->size);
+ printf(" - offset = %u, size = %u", u->offset, u->size);
+ if (sizeof(*u) + u->size <= data_size) {
+ printf(": ");
+ print_data(u + 1, u->size);
+ } else {
+ printf(" (too large)");
+ }
printf("\n");
break;
}
case MAIL_TRANSACTION_EXT_HDR_UPDATE32: {
const struct mail_transaction_ext_hdr_update32 *u = data;
- printf(" - offset = %u, size = %u: ", u->offset, u->size);
- print_data(u + 1, u->size);
+ printf(" - offset = %u, size = %u", u->offset, u->size);
+ if (sizeof(*u) + u->size <= data_size) {
+ printf(": ");
+ print_data(u + 1, u->size);
+ } else {
+ printf(" (too large)");
+ }
printf("\n");
break;
}
@@ -352,7 +369,10 @@
record_size = (sizeof(*rec) + prev_intro.record_size + 3) & ~3;
while (rec < end) {
printf(" - uid=%u: ", rec->uid);
- print_data(rec + 1, prev_intro.record_size);
+ if (prev_intro.record_size <= (char*)end - (char *)(rec+1))
+ print_data(rec + 1, prev_intro.record_size);
+ else
+ printf("(record_size too large)");
printf("\n");
rec = CONST_PTR_OFFSET(rec, record_size);
}
@@ -507,7 +527,7 @@
i_fatal("rec data read() %"PRIuSIZE_T" != %"PRIuSIZE_T,
ret, hdr.size - sizeof(hdr));
}
- log_record_print(&hdr, buf, modseq);
+ log_record_print(&hdr, buf, (size_t)ret, modseq);
} else {
if (lseek(fd, hdr.size - sizeof(hdr), SEEK_CUR) < 0)
i_fatal("lseek() failed: %m");
More information about the dovecot-cvs
mailing list