mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
Merge branch '1857-assertion-failure-insist-nlabels-name-labels' into 'master'
Resolve "assertion failure in 9.16.2: name.c:1738: INSIST(nlabels == name->labels)" Closes #1857 See merge request isc-projects/bind9!3577
This commit is contained in:
4
CHANGES
4
CHANGES
@@ -1,3 +1,7 @@
|
||||
5421. [bug] Fixed a race that could cause named to crash when
|
||||
looking up the nodename of an RBT node if the tree
|
||||
was modified. [GL #1857]
|
||||
|
||||
5420. [bug] Add missing isc_{mutex,conditional}_destroy calls
|
||||
that caused a memory leak on FreeBSD. [GL #1893]
|
||||
|
||||
|
@@ -123,4 +123,8 @@ Bug Fixes
|
||||
addzone``. Thanks to Alberto Fernández. [GL #1695]
|
||||
|
||||
- Missing mutex and conditional destruction in netmgr code leads to a
|
||||
memory leak on *BSD systems. [GL #1893]
|
||||
memory leak on BSD systems. [GL #1893]
|
||||
|
||||
- ``named`` could crash with an assertion failure if the name of a
|
||||
database node was looked up while the database was being modified.
|
||||
[GL #1857]
|
||||
|
@@ -561,6 +561,8 @@ rdataset_addglue(dns_rdataset_t *rdataset, dns_dbversion_t *version,
|
||||
dns_message_t *msg);
|
||||
static void
|
||||
free_gluetable(rbtdb_version_t *version);
|
||||
static isc_result_t
|
||||
nodefullname(dns_db_t *db, dns_dbnode_t *node, dns_name_t *name);
|
||||
|
||||
static dns_rdatasetmethods_t rdataset_methods = { rdataset_disassociate,
|
||||
rdataset_first,
|
||||
@@ -5958,14 +5960,14 @@ update_recordsandxfrsize(bool add, rbtdb_version_t *rbtversion,
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||||
rdatasetheader_t *newheader, unsigned int options, bool loading,
|
||||
dns_rdataset_t *addedrdataset, isc_stdtime_t now) {
|
||||
add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, const dns_name_t *nodename,
|
||||
rbtdb_version_t *rbtversion, rdatasetheader_t *newheader,
|
||||
unsigned int options, bool loading, dns_rdataset_t *addedrdataset,
|
||||
isc_stdtime_t now) {
|
||||
rbtdb_changed_t *changed = NULL;
|
||||
rdatasetheader_t *topheader, *topheader_prev, *header, *sigheader;
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *nodename = dns_fixedname_initname(&fname);
|
||||
unsigned char *merged;
|
||||
rdatasetheader_t *topheader = NULL, *topheader_prev = NULL;
|
||||
rdatasetheader_t *header = NULL, *sigheader = NULL;
|
||||
unsigned char *merged = NULL;
|
||||
isc_result_t result;
|
||||
bool header_nx;
|
||||
bool newheader_nx;
|
||||
@@ -5983,8 +5985,6 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||||
* Caller must be holding the node lock.
|
||||
*/
|
||||
|
||||
dns_rbt_fullnamefromnode(rbtnode, nodename);
|
||||
|
||||
if ((options & DNS_DBADD_MERGE) != 0) {
|
||||
REQUIRE(rbtversion != NULL);
|
||||
merge = true;
|
||||
@@ -6667,9 +6667,7 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
}
|
||||
|
||||
name = dns_fixedname_initname(&fixed);
|
||||
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
|
||||
dns_rbt_fullnamefromnode(node, name);
|
||||
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
|
||||
nodefullname(db, node, name);
|
||||
dns_rdataset_getownercase(rdataset, name);
|
||||
|
||||
newheader = (rdatasetheader_t *)region.base;
|
||||
@@ -6761,10 +6759,11 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
|
||||
|
||||
/*
|
||||
* If we're adding a delegation type, adding to the auxiliary NSEC tree,
|
||||
* or the DB is a cache in an overmem state, hold an exclusive lock on
|
||||
* the tree. In the latter case the lock does not necessarily have to
|
||||
* be acquired but it will help purge ancient entries more effectively.
|
||||
* If we're adding a delegation type, adding to the auxiliary NSEC
|
||||
* tree, or the DB is a cache in an overmem state, hold an
|
||||
* exclusive lock on the tree. In the latter case the lock does
|
||||
* not necessarily have to be acquired but it will help purge
|
||||
* ancient entries more effectively.
|
||||
*/
|
||||
if (IS_CACHE(rbtdb) && isc_mem_isovermem(rbtdb->common.mctx)) {
|
||||
cache_is_overmem = true;
|
||||
@@ -6811,7 +6810,6 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
if (newnsec) {
|
||||
dns_rbtnode_t *nsecnode;
|
||||
|
||||
dns_rbt_fullnamefromnode(rbtnode, name);
|
||||
nsecnode = NULL;
|
||||
result = dns_rbt_addnode(rbtdb->nsec, name, &nsecnode);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
@@ -6824,8 +6822,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
}
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = add32(rbtdb, rbtnode, rbtversion, newheader, options,
|
||||
false, addedrdataset, now);
|
||||
result = add32(rbtdb, rbtnode, name, rbtversion, newheader,
|
||||
options, false, addedrdataset, now);
|
||||
}
|
||||
if (result == ISC_R_SUCCESS && delegating) {
|
||||
rbtnode->find_callback = 1;
|
||||
@@ -6867,8 +6865,6 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
REQUIRE(VALID_RBTDB(rbtdb));
|
||||
REQUIRE(rbtversion != NULL && rbtversion->rbtdb == rbtdb);
|
||||
|
||||
dns_rbt_fullnamefromnode(rbtnode, nodename);
|
||||
|
||||
if (rbtdb->common.methods == &zone_methods) {
|
||||
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
|
||||
REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 &&
|
||||
@@ -6880,6 +6876,8 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
|
||||
}
|
||||
|
||||
nodefullname(db, node, nodename);
|
||||
|
||||
result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx,
|
||||
®ion, sizeof(rdatasetheader_t));
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
@@ -7080,6 +7078,8 @@ deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
|
||||
dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
|
||||
rbtdb_version_t *rbtversion = version;
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *nodename = dns_fixedname_initname(&fname);
|
||||
isc_result_t result;
|
||||
rdatasetheader_t *newheader;
|
||||
|
||||
@@ -7113,12 +7113,12 @@ deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
newheader->last_used = 0;
|
||||
newheader->node = rbtnode;
|
||||
|
||||
nodefullname(db, node, nodename);
|
||||
|
||||
NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
|
||||
isc_rwlocktype_write);
|
||||
|
||||
result = add32(rbtdb, rbtnode, rbtversion, newheader, DNS_DBADD_FORCE,
|
||||
false, NULL, 0);
|
||||
|
||||
result = add32(rbtdb, rbtnode, nodename, rbtversion, newheader,
|
||||
DNS_DBADD_FORCE, false, NULL, 0);
|
||||
NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
|
||||
isc_rwlocktype_write);
|
||||
|
||||
@@ -7227,12 +7227,6 @@ loading_addrdataset(void *arg, const dns_name_t *name,
|
||||
|
||||
REQUIRE(rdataset->rdclass == rbtdb->common.rdclass);
|
||||
|
||||
/*
|
||||
* This routine does no node locking. See comments in
|
||||
* 'load' below for more information on loading and
|
||||
* locking.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SOA records are only allowed at top of zone.
|
||||
*/
|
||||
@@ -7284,9 +7278,6 @@ loading_addrdataset(void *arg, const dns_name_t *name,
|
||||
return (result);
|
||||
}
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
dns_name_t foundname;
|
||||
dns_name_init(&foundname, NULL);
|
||||
dns_rbt_namefromnode(node, &foundname);
|
||||
node->locknum = node->hashval % rbtdb->node_lock_count;
|
||||
}
|
||||
|
||||
@@ -7323,10 +7314,8 @@ loading_addrdataset(void *arg, const dns_name_t *name,
|
||||
}
|
||||
|
||||
NODE_LOCK(&rbtdb->node_locks[node->locknum].lock, isc_rwlocktype_write);
|
||||
|
||||
result = add32(rbtdb, node, rbtdb->current_version, newheader,
|
||||
result = add32(rbtdb, node, name, rbtdb->current_version, newheader,
|
||||
DNS_DBADD_MERGE, true, NULL, 0);
|
||||
|
||||
NODE_UNLOCK(&rbtdb->node_locks[node->locknum].lock,
|
||||
isc_rwlocktype_write);
|
||||
|
||||
|
Reference in New Issue
Block a user