]> 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:25:13 +0000 (18:25 -0700)
(cherry picked from commit 0db7130f2b4ae24c3f32e95325673688f16b54f0)

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

index 09f665e6c8b27f2d49476986db39dcbd7dad7a9c..6491a7f7cbb82ee50d2b92263d742a6b2645b8ce 100644 (file)
@@ -1010,7 +1010,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;
 
@@ -1040,6 +1040,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);
@@ -1142,6 +1146,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
@@ -1662,7 +1678,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 a9c1cc63c555fb77b0bfe12f28abfa440744a71f..eb1261b1a51613a8d76d19a907844d65d41d347e 100644 (file)
@@ -15084,6 +15084,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)