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.9.13rc2~2^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e7506b6a70d16c5565e147cbfd5b07af8a7ad68a;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 da70007f9a3..58f0338af65 100644 --- a/lib/dns/journal.c +++ b/lib/dns/journal.c @@ -1013,7 +1013,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; @@ -1043,6 +1043,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); @@ -1145,6 +1149,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 @@ -1670,7 +1686,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 7971f7ffa02..ca1c06fda8c 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -14281,6 +14281,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)