1927. [bug] Access to soanode or nsnode in rbtdb violated the

lock order rule and could cause a dead lock.
                        [RT# 15518]
This commit is contained in:
Mark Andrews 2005-10-13 01:58:32 +00:00
parent 037b732f88
commit 982e072a50
7 changed files with 36 additions and 192 deletions

View file

@ -1,6 +1,8 @@
1928. [bug] Race in rbtdb.c:currentversion(). [RT #15517]
1927. [placeholder] rt15518
1927. [bug] Access to soanode or nsnode in rbtdb violated the
lock order rule and could cause a dead lock.
[RT# 15518]
1926. [bug] The Windows installer did not check for empty
passwords. BINDinstall was being installed in

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: query.c,v 1.273 2005/09/05 00:10:52 marka Exp $ */
/* $Id: query.c,v 1.274 2005/10/13 01:58:31 marka Exp $ */
/*! \file */
@ -2013,7 +2013,7 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version,
/*
* Find the SOA.
*/
result = dns_db_getsoanode(db, &node);
result = dns_db_getoriginnode(db, &node);
if (result == ISC_R_SUCCESS) {
result = dns_db_findrdataset(db, node, version,
dns_rdatatype_soa,
@ -2029,9 +2029,6 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version,
result = dns_db_find(db, name, version, dns_rdatatype_soa,
client->query.dboptions, 0, &node,
fname, rdataset, sigrdataset);
if (result == ISC_R_SUCCESS)
(void)dns_db_setsoanode(db, node);
}
if (result != ISC_R_SUCCESS) {
/*
@ -2135,7 +2132,7 @@ query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) {
/*
* Find the NS rdataset.
*/
result = dns_db_getnsnode(db, &node);
result = dns_db_getoriginnode(db, &node);
if (result == ISC_R_SUCCESS) {
result = dns_db_findrdataset(db, node, version,
dns_rdatatype_ns,
@ -2147,9 +2144,6 @@ query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) {
client->query.dboptions, 0, &node,
fname, rdataset, sigrdataset);
CTRACE("query_addns: dns_db_find complete");
if (result == ISC_R_SUCCESS)
(void)dns_db_setnsnode(db, node);
}
if (result != ISC_R_SUCCESS) {
CTRACE("query_addns: "

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: db.c,v 1.79 2005/06/28 02:55:09 marka Exp $ */
/* $Id: db.c,v 1.80 2005/10/13 01:58:31 marka Exp $ */
/*! \file */
@ -809,49 +809,13 @@ dns_db_unregister(dns_dbimplementation_t **dbimp) {
}
isc_result_t
dns_db_getsoanode(dns_db_t *db, dns_dbnode_t **nodep) {
dns_db_getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
REQUIRE(DNS_DB_VALID(db));
REQUIRE(dns_db_iszone(db) == ISC_TRUE);
REQUIRE(nodep != NULL && *nodep == NULL);
if (db->methods->getsoanode != NULL)
return ((db->methods->getsoanode)(db, nodep));
if (db->methods->getoriginnode != NULL)
return ((db->methods->getoriginnode)(db, nodep));
return (ISC_R_NOTFOUND);
}
isc_result_t
dns_db_setsoanode(dns_db_t *db, dns_dbnode_t *node) {
REQUIRE(DNS_DB_VALID(db));
REQUIRE(dns_db_iszone(db) == ISC_TRUE);
REQUIRE(node != NULL);
if (db->methods->setsoanode != NULL)
return ((db->methods->setsoanode)(db, node));
return (ISC_R_FAILURE);
}
isc_result_t
dns_db_getnsnode(dns_db_t *db, dns_dbnode_t **nodep) {
REQUIRE(DNS_DB_VALID(db));
REQUIRE(dns_db_iszone(db) == ISC_TRUE);
REQUIRE(nodep != NULL && *nodep == NULL);
if (db->methods->getnsnode != NULL)
return ((db->methods->getnsnode)(db, nodep));
return (ISC_R_NOTFOUND);
}
isc_result_t
dns_db_setnsnode(dns_db_t *db, dns_dbnode_t *node) {
REQUIRE(DNS_DB_VALID(db));
REQUIRE(dns_db_iszone(db) == ISC_TRUE);
REQUIRE(node != NULL);
if (db->methods->setnsnode != NULL)
return ((db->methods->setnsnode)(db, node));
return (ISC_R_FAILURE);
}

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: db.h,v 1.83 2005/07/18 05:58:58 marka Exp $ */
/* $Id: db.h,v 1.84 2005/10/13 01:58:32 marka Exp $ */
#ifndef DNS_DB_H
#define DNS_DB_H 1
@ -145,10 +145,7 @@ typedef struct dns_dbmethods {
isc_boolean_t (*ispersistent)(dns_db_t *db);
void (*overmem)(dns_db_t *db, isc_boolean_t overmem);
void (*settask)(dns_db_t *db, isc_task_t *);
isc_result_t (*getsoanode)(dns_db_t *db, dns_dbnode_t **nodep);
isc_result_t (*setsoanode)(dns_db_t *db, dns_dbnode_t *nodep);
isc_result_t (*getnsnode)(dns_db_t *db, dns_dbnode_t **nodep);
isc_result_t (*setnsnode)(dns_db_t *db, dns_dbnode_t *nodep);
isc_result_t (*getoriginnode)(dns_db_t *db, dns_dbnode_t **nodep);
} dns_dbmethods_t;
typedef isc_result_t
@ -1278,9 +1275,11 @@ dns_db_unregister(dns_dbimplementation_t **dbimp);
*/
isc_result_t
dns_db_getsoanode(dns_db_t *db, dns_dbnode_t **nodep);
dns_db_getoriginnode(dns_db_t *db, dns_dbnode_t **nodep);
/*%<
* Get a cached SOA DB node corresponding to the DB's zone.
* Get the origin DB node corresponding to the DB's zone. This function
* should typically succeed unless the underlying DB implementation doesn't
* support the feature.
*
* Requires:
*
@ -1288,71 +1287,11 @@ dns_db_getsoanode(dns_db_t *db, dns_dbnode_t **nodep);
* \li 'nodep' != NULL && '*nodep' == NULL
*
* Ensures:
* \li On sucess, '*nodep' will point to a DB node for the SOA RR of 'db.'
* \li On success, '*nodep' will point to the DB node of the zone's origin.
*
* Returns:
* \li #ISC_R_SUCCESS
* \li #ISC_R_NOTFOUND - an SOA RR node has not been cached in 'db' or SOA RR
* caching is not supported for 'db'
*/
isc_result_t
dns_db_setsoanode(dns_db_t *db, dns_dbnode_t *node);
/*%<
* Set an SOA DB node as cache corresponding to the DB's zone. If there is
* already a node set in the DB, it will be detached and replaced with the
* new one.
*
* Requires:
*
* \li 'db' is a valid zone database.
* \li 'node' is a valid DB node.
*
* Ensures:
* \li On sucess, '*nodep' will point to a DB node for the SOA RR of 'db.'
*
* Returns:
* \li #ISC_R_SUCCESS
* \li #ISC_R_FAILURE - SOA RR caching is not supported for 'db'
*/
isc_result_t
dns_db_getnsnode(dns_db_t *db, dns_dbnode_t **nodep);
/*%<
* Get a cached NS DB node corresponding to the DB's zone.
*
* Requires:
*
* \li 'db' is a valid zone database.
* \li 'nodep' != NULL && '*nodep' == NULL
*
* Ensures:
* \li On sucess, '*nodep' will point to a DB node for the NS RR of 'db.'
*
* Returns:
* \li #ISC_R_SUCCESS
* \li #ISC_R_NOTFOUND - an NS RR node has not been cached in 'db' or NS RR
* caching is not supported for 'db'
*/
isc_result_t
dns_db_setnsnode(dns_db_t *db, dns_dbnode_t *node);
/*%<
* Set an NS DB node as cache corresponding to the DB's zone. If there is
* already a node set in the DB, it will be detached and replaced with the
* new one.
*
* Requires:
*
* \li 'db' is a valid zone database.
* \li 'node' is a valid DB node.
*
* Ensures:
* \li On sucess, '*nodep' will point to a DB node for the NS RR of 'db.'
*
* Returns:
* \li #ISC_R_SUCCESS
* \li #ISC_R_FAILURE - NS RR caching is not supported for 'db'
* \li #ISC_R_NOTFOUND - the DB implementation does not support this feature.
*/
ISC_LANG_ENDDECLS

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rbtdb.c,v 1.221 2005/10/13 01:19:14 marka Exp $ */
/* $Id: rbtdb.c,v 1.222 2005/10/13 01:58:31 marka Exp $ */
/*! \file */
@ -5272,73 +5272,30 @@ ispersistent(dns_db_t *db) {
}
static isc_result_t
getsoanode(dns_db_t *db, dns_dbnode_t **nodep) {
getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
dns_rbtnode_t *onode;
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(VALID_RBTDB(rbtdb));
REQUIRE(nodep != NULL && *nodep == NULL);
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
if (rbtdb->soanode != NULL) {
attachnode(db, rbtdb->soanode, nodep);
} else
/* Note that the access to origin_node doesn't require a DB lock */
onode = (dns_rbtnode_t *)rbtdb->origin_node;
if (onode != NULL) {
NODE_STRONGLOCK(&rbtdb->node_locks[onode->locknum].lock);
new_reference(rbtdb, onode);
NODE_STRONGUNLOCK(&rbtdb->node_locks[onode->locknum].lock);
*nodep = rbtdb->origin_node;
} else {
INSIST(!IS_CACHE(rbtdb));
result = ISC_R_NOTFOUND;
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
}
return (result);
}
static isc_result_t
setsoanode(dns_db_t *db, dns_dbnode_t *node) {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
REQUIRE(VALID_RBTDB(rbtdb));
REQUIRE(node != NULL);
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
if (rbtdb->soanode != NULL)
detachnode(db, &rbtdb->soanode);
attachnode(db, node, &rbtdb->soanode);
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
return (ISC_R_SUCCESS);
}
static isc_result_t
getnsnode(dns_db_t *db, dns_dbnode_t **nodep) {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(VALID_RBTDB(rbtdb));
REQUIRE(nodep != NULL && *nodep == NULL);
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
if (rbtdb->nsnode != NULL) {
attachnode(db, rbtdb->nsnode, nodep);
} else
result = ISC_R_NOTFOUND;
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
return (result);
}
static isc_result_t
setnsnode(dns_db_t *db, dns_dbnode_t *node) {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
REQUIRE(VALID_RBTDB(rbtdb));
REQUIRE(node != NULL);
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
if (rbtdb->nsnode != NULL)
detachnode(db, &rbtdb->nsnode);
attachnode(db, node, &rbtdb->nsnode);
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
return (ISC_R_SUCCESS);
}
static dns_dbmethods_t zone_methods = {
attach,
detach,
@ -5367,10 +5324,7 @@ static dns_dbmethods_t zone_methods = {
ispersistent,
overmem,
settask,
getsoanode,
setsoanode,
getnsnode,
setnsnode
getoriginnode
};
static dns_dbmethods_t cache_methods = {
@ -5401,10 +5355,7 @@ static dns_dbmethods_t cache_methods = {
ispersistent,
overmem,
settask,
getsoanode,
setsoanode,
getnsnode,
setnsnode
getoriginnode
};
isc_result_t

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: sdb.c,v 1.52 2005/08/18 00:57:29 marka Exp $ */
/* $Id: sdb.c,v 1.53 2005/10/13 01:58:32 marka Exp $ */
/*! \file */
@ -1240,9 +1240,6 @@ static dns_dbmethods_t sdb_methods = {
ispersistent,
overmem,
settask,
NULL,
NULL,
NULL,
NULL
};

View file

@ -50,7 +50,7 @@
* USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: sdlz.c,v 1.4 2005/09/20 06:16:26 marka Exp $ */
/* $Id: sdlz.c,v 1.5 2005/10/13 01:58:32 marka Exp $ */
/*! \file */
@ -1043,9 +1043,6 @@ static dns_dbmethods_t sdlzdb_methods = {
overmem,
settask,
NULL,
NULL,
NULL,
NULL
};
/*