From: Witold Kręcicki Date: Tue, 26 Jun 2018 19:06:55 +0000 (+0200) Subject: Fix some issues with large journal entries X-Git-Tag: v9.10.8rc2~1^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=56554dadd242dcfe4e40fe6d57c5932c31c92952;p=thirdparty%2Fbind9.git Fix some issues with large journal entries (cherry picked from commit 0db7130f2b4ae24c3f32e95325673688f16b54f0) (cherry picked from commit 1919f5c93781ac79b8fab2275c1ab6b4b794cb8b) --- diff --git a/lib/dns/journal.c b/lib/dns/journal.c index 1406655408a..227e48b0701 100644 --- a/lib/dns/journal.c +++ b/lib/dns/journal.c @@ -1014,7 +1014,7 @@ dns_journal_writediff(dns_journal_t *j, dns_diff_t *diff) { dns_difftuple_t *t; isc_buffer_t buffer; void *mem = NULL; - unsigned int size; + size_t size; isc_result_t result; isc_region_t used; @@ -1044,6 +1044,10 @@ dns_journal_writediff(dns_journal_t *j, dns_diff_t *diff) { size += t->rdata.length; } + if (size >= DNS_JOURNAL_SIZE_MAX) { + return (ISC_R_RANGE); + } + mem = isc_mem_get(j->mctx, size); if (mem == NULL) return (ISC_R_NOMEMORY); @@ -1146,6 +1150,18 @@ dns_journal_commit(dns_journal_t *j) { } } + /* + * We currently don't support huge journal entries. + */ + unsigned long long total = j->x.pos[1].offset - j->x.pos[0].offset; + if (total >= DNS_JOURNAL_SIZE_MAX) { + isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, + "transaction too big to be stored in journal :" + "%llub (max is %llub)", total, + (unsigned long long)DNS_JOURNAL_SIZE_MAX); + return (ISC_R_UNEXPECTED); + } + /* * Some old journal entries may become non-addressable * when we increment the current serial number. Purge them @@ -1661,7 +1677,12 @@ read_one_rr(dns_journal_t *j) { journal_xhdr_t xhdr; journal_rrhdr_t rrhdr; - INSIST(j->offset <= j->it.epos.offset); + if (j->offset > j->it.epos.offset) { + isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR, + "%s: journal corrupt: possible integer overflow", + j->filename); + return (ISC_R_UNEXPECTED); + } if (j->offset == j->it.epos.offset) return (ISC_R_NOMORE); if (j->it.xpos == j->it.xsize) { diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 08823b9ddbd..f9474bb0c8a 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -14784,6 +14784,13 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL, zone->journal); + if (result == ISC_R_RANGE) { + dns_zone_log(zone, ISC_LOG_ERROR, + "ixfr-from-differences: failed: " + "difference too big to be stored " + "in journal"); + goto fail; + } if (result != ISC_R_SUCCESS) goto fail; if (dump)