]> 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 02:36:46 +0000 (19:36 -0700)
(cherry picked from commit 0db7130f2b4ae24c3f32e95325673688f16b54f0)
(cherry picked from commit 1919f5c93781ac79b8fab2275c1ab6b4b794cb8b)

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

index da70007f9a3d9c14c2b62aeb286c6e2bc550e4e3..58f0338af65a98d95ca64f18d782b2210293347c 100644 (file)
@@ -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) {
index 7971f7ffa02d1584b2b0047d435f1970550c3aa0..ca1c06fda8cbe7c6048e57f89272487067242f57 100644 (file)
@@ -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)