mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-09 13:42:06 -04:00
Merge branch '339-issues-with-large-journal-entries-v9_11-v9_9' into 'v9_9'
Fix handling of large journal entries. See merge request isc-projects/bind9!448
This commit is contained in:
commit
9a06973e09
4 changed files with 48 additions and 6 deletions
3
CHANGES
3
CHANGES
|
|
@ -1,3 +1,6 @@
|
|||
4984. [bug] Improve handling of very large incremental
|
||||
zone transfers to prevent journal corruption. [GL #339]
|
||||
|
||||
4979. [bug] Non-libcap builds were not checking whether all
|
||||
requested capabilities are present in the permitted
|
||||
capability set. [GL #321]
|
||||
|
|
|
|||
|
|
@ -90,6 +90,14 @@
|
|||
|
||||
<section xml:id="relnotes_bugs"><info><title>Bug Fixes</title></info>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<command>named</command> now rejects excessively large
|
||||
incremental (IXFR) zone transfers in order to prevent
|
||||
possible corruption of journal files which could cause
|
||||
<command>named</command> to abort when loading zones. [GL #339]
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<command>rndc reload</command> could cause <command>named</command>
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: journal.c,v 1.120 2011/12/22 07:32:41 each Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
|
@ -1013,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;
|
||||
isc_uint64_t size;
|
||||
isc_result_t result;
|
||||
isc_region_t used;
|
||||
|
||||
|
|
@ -1043,6 +1041,14 @@ dns_journal_writediff(dns_journal_t *j, dns_diff_t *diff) {
|
|||
size += t->rdata.length;
|
||||
}
|
||||
|
||||
if (size >= ISC_INT32_MAX) {
|
||||
isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
|
||||
"dns_journal_writediff: %s: journal entry "
|
||||
"too big to be stored: %llu bytes", j->filename,
|
||||
size);
|
||||
return (ISC_R_NOSPACE);
|
||||
}
|
||||
|
||||
mem = isc_mem_get(j->mctx, size);
|
||||
if (mem == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
|
@ -1096,6 +1102,7 @@ isc_result_t
|
|||
dns_journal_commit(dns_journal_t *j) {
|
||||
isc_result_t result;
|
||||
journal_rawheader_t rawheader;
|
||||
isc_uint64_t total;
|
||||
|
||||
REQUIRE(DNS_JOURNAL_VALID(j));
|
||||
REQUIRE(j->state == JOURNAL_STATE_TRANSACTION ||
|
||||
|
|
@ -1145,6 +1152,18 @@ dns_journal_commit(dns_journal_t *j) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We currently don't support huge journal entries.
|
||||
*/
|
||||
total = j->x.pos[1].offset - j->x.pos[0].offset;
|
||||
if (total >= ISC_INT32_MAX) {
|
||||
isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
|
||||
"transaction too big to be stored in journal: "
|
||||
"%llub (max is %llub)", total,
|
||||
(isc_uint64_t)ISC_INT32_MAX);
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
|
||||
/*
|
||||
* Some old journal entries may become non-addressable
|
||||
* when we increment the current serial number. Purge them
|
||||
|
|
@ -1670,7 +1689,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) {
|
||||
|
|
|
|||
|
|
@ -14281,8 +14281,14 @@ 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_SUCCESS)
|
||||
goto fail;
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
isc__strerror(errno, strbuf, sizeof(strbuf));
|
||||
dns_zone_log(zone, ISC_LOG_ERROR,
|
||||
"ixfr-from-differences: failed: "
|
||||
"%s", strbuf);
|
||||
goto fallback;
|
||||
}
|
||||
if (dump)
|
||||
zone_needdump(zone, DNS_DUMP_DELAY);
|
||||
else if (zone->journalsize != -1) {
|
||||
|
|
@ -14306,6 +14312,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
|
|||
if (zone->type == dns_zone_master && inline_raw(zone))
|
||||
zone_send_secureserial(zone, serial);
|
||||
} else {
|
||||
fallback:
|
||||
if (dump && zone->masterfile != NULL) {
|
||||
/*
|
||||
* If DNS_ZONEFLG_FORCEXFER was set we don't want
|
||||
|
|
|
|||
Loading…
Reference in a new issue