]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
1927. [bug] Access to soanode or nsnode in rbtdb violated the
authorMark Andrews <marka@isc.org>
Thu, 13 Oct 2005 02:12:25 +0000 (02:12 +0000)
committerMark Andrews <marka@isc.org>
Thu, 13 Oct 2005 02:12:25 +0000 (02:12 +0000)
                        lock order rule and could cause a dead lock.
                        [RT# 15518]

CHANGES
bin/named/query.c
lib/dns/db.c
lib/dns/include/dns/db.h
lib/dns/rbtdb.c
lib/dns/sdb.c
lib/dns/sdlz.c

diff --git a/CHANGES b/CHANGES
index 284ae64e7a51cc576257926fe52c2b6feab6e17d..be00195ddd334b32f959af9c1e719b9afd6d3717 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,9 @@
 1928.  [bug]           Race in rbtdb.c:currentversion(). [RT #15517]
 
+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
                        the wrong place. [RT #15483]
index 6c597dd58c8ca44f2496f23f21e7d05cfa8da964..4b7c2920a98950be4a09c6e266a80d24211fadae 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: query.c,v 1.257.18.17 2005/09/05 00:18:11 marka Exp $ */
+/* $Id: query.c,v 1.257.18.18 2005/10/13 02:12:23 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: "
index 1ee73e41a258764883b802c5be24eb0e9876de6e..32ff6aebb7bd979a96cb327d5393757fdd098944 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: db.c,v 1.74.18.5 2005/06/28 03:00:20 marka Exp $ */
+/* $Id: db.c,v 1.74.18.6 2005/10/13 02:12:24 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);
-}
index fbff44ceb8c24ab0e1ff54124a51b0f2b3d3e0d3..a791a2e3913dae80e2307c8ec5d09c0ab9002d78 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: db.h,v 1.76.18.6 2005/06/28 03:00:21 marka Exp $ */
+/* $Id: db.h,v 1.76.18.7 2005/10/13 02:12:25 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
index 81000fb7aabba399a1b361dccda8f787758fd77a..a116631283a3951720609d4df965efaf45afd732 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rbtdb.c,v 1.196.18.23 2005/10/13 01:26:06 marka Exp $ */
+/* $Id: rbtdb.c,v 1.196.18.24 2005/10/13 02:12:24 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
-               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);
+       /* 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);
 
-       RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
-       if (rbtdb->nsnode != NULL) {
-               attachnode(db, rbtdb->nsnode, nodep);
-       } else
+               *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
-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
index 81ac20d30d4bf07213430fd49548c25c91881d27..1724256d794b8ba82883c6c758a59b754814e597 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: sdb.c,v 1.45.18.7 2005/08/18 01:03:01 marka Exp $ */
+/* $Id: sdb.c,v 1.45.18.8 2005/10/13 02:12:25 marka Exp $ */
 
 /*! \file */
 
@@ -1240,9 +1240,6 @@ static dns_dbmethods_t sdb_methods = {
        ispersistent,
        overmem,
        settask,
-       NULL,
-       NULL,
-       NULL,
        NULL
 };
 
index 9155d2027a79a534b4693af5c4604f26a76905d0..b3fbc3b9550fd3e0dca63ab3bf2509d9b6d98199 100644 (file)
@@ -50,7 +50,7 @@
  * USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: sdlz.c,v 1.2.2.2 2005/09/06 03:47:17 marka Exp $ */
+/* $Id: sdlz.c,v 1.2.2.3 2005/10/13 02:12:25 marka Exp $ */
 
 /*! \file */
 
@@ -1043,9 +1043,6 @@ static dns_dbmethods_t sdlzdb_methods = {
        overmem,
        settask,
        NULL,
-       NULL,
-       NULL,
-       NULL
 };
 
 /*