diff --git a/lib/dns/journal.c b/lib/dns/journal.c index d89ea4db1c..4b152e93d6 100644 --- a/lib/dns/journal.c +++ b/lib/dns/journal.c @@ -1011,7 +1011,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; @@ -1041,6 +1041,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); @@ -1143,6 +1147,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 @@ -1663,7 +1679,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 e912a4047e..498030be02 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15032,6 +15032,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)