]> 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:56:31 +0000 (18:56 -0700)
(cherry picked from commit 0db7130f2b4ae24c3f32e95325673688f16b54f0)
(cherry picked from commit 1919f5c93781ac79b8fab2275c1ab6b4b794cb8b)

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

index 1406655408a0a356d7b915fd6cb5265930eaf774..227e48b0701f01864da600539b0e2ed8bc09a2f9 100644 (file)
@@ -1014,7 +1014,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;
 
@@ -1044,6 +1044,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);
@@ -1146,6 +1150,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
@@ -1661,7 +1677,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 08823b9ddbdf2c176261f916143ddb4b3cc15215..f9474bb0c8acf1a1bb175576c6c4461a210c1f6b 100644 (file)
@@ -14784,6 +14784,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)