]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix some issues with large journal entries
authorWitold Kręcicki <wpk@isc.org>
Tue, 26 Jun 2018 19:06:55 +0000 (21:06 +0200)
committerEvan Hunt <each@isc.org>
Thu, 28 Jun 2018 01:33:32 +0000 (18:33 -0700)
(cherry picked from commit 0db7130f2b4ae24c3f32e95325673688f16b54f0)

lib/dns/journal.c
lib/dns/zone.c

index 86764ce979da9b9c6c2816fc381a7f18755296a3..45b59ace482ef4e4d18d3bfc6daea4b7c4a73758 100644 (file)
@@ -1012,7 +1012,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;
 
@@ -1042,6 +1042,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);
@@ -1144,6 +1148,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
@@ -1659,7 +1675,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) {
index b23c75a99a579dbc00d6cc12106d0733b1e93a99..224431bb8c622330850eceb5cc7bced17a82cbe3 100644 (file)
@@ -14986,6 +14986,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)