]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2124. [bug] It was possible to dereference a freed fetch
authorMark Andrews <marka@isc.org>
Mon, 8 Jan 2007 00:45:12 +0000 (00:45 +0000)
committerMark Andrews <marka@isc.org>
Mon, 8 Jan 2007 00:45:12 +0000 (00:45 +0000)
                        context. [RT #16584]

CHANGES
bin/named/query.c
lib/dns/resolver.c
util/update_copyrights

diff --git a/CHANGES b/CHANGES
index e4c54455b765b09f35bfd5f744ab8d30160c8a96..4d4f9d967da400b85c94fed68068ddaa7bbe1a5a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+2124.  [bug]           It was possible to dereference a freed fetch
+                       context. [RT #16584]
+
 2120.  [doc]           Fix markup on nsupdate man page. [RT #16556]
 
        --- 9.4.0rc1 released ---
index 29a62f07925e019b815737dfdcb917a885f6fe01..c0667361ec0250f67489f2a2f72e8bbc6c8f8189 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: query.c,v 1.257.18.34 2006/12/07 04:38:39 marka Exp $ */
+/* $Id: query.c,v 1.257.18.35 2007/01/08 00:45:11 marka Exp $ */
 
 /*! \file */
 
@@ -3877,6 +3877,9 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
                 * resolver and not have it cached.
                 */
                if (qtype == dns_rdatatype_soa &&
+#ifdef DLZ
+                   zone != NULL &&
+#endif
                    dns_zone_getzeronosoattl(zone))
                        result = query_addsoa(client, db, version, ISC_TRUE);
                else
index a05a57fe4f3e7f8eba19ba35b9855dd3e98de04f..cfaf24b06a25f9ea9eeb3845ca161539f9848b86 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: resolver.c,v 1.284.18.53 2006/12/07 06:50:34 marka Exp $ */
+/* $Id: resolver.c,v 1.284.18.54 2007/01/08 00:45:11 marka Exp $ */
 
 /*! \file */
 
@@ -223,6 +223,11 @@ struct fetchctx {
        dns_name_t                      nsname; 
        dns_fetch_t *                   nsfetch;
        dns_rdataset_t                  nsrrset;
+
+       /*%
+        * Number of queries that reference this context.
+        */
+       unsigned int                    nqueries;
 };
 
 #define FCTX_MAGIC                     ISC_MAGIC('F', '!', '!', '!')
@@ -362,6 +367,7 @@ static isc_result_t ncache_adderesult(dns_message_t *message,
                                      dns_rdataset_t *ardataset,
                                      isc_result_t *eresultp);
 static void validated(isc_task_t *task, isc_event_t *event); 
+static void maybe_destroy(fetchctx_t *fctx);
 
 static isc_result_t
 valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name,
@@ -528,6 +534,9 @@ resquery_destroy(resquery_t **queryp) {
 
        INSIST(query->tcpsocket == NULL);
 
+       query->fctx->nqueries--;
+       if (SHUTTINGDOWN(query->fctx))
+               maybe_destroy(query->fctx);     /* Locks bucket. */
        query->magic = 0;
        isc_mem_put(query->mctx, query, sizeof(*query));
        *queryp = NULL;
@@ -1180,6 +1189,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
        }
 
        ISC_LIST_APPEND(fctx->queries, query, link);
+       query->fctx->nqueries++;
 
        return (ISC_R_SUCCESS);
 
@@ -1720,7 +1730,7 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
                        want_done = ISC_TRUE;
                }
        } else if (SHUTTINGDOWN(fctx) && fctx->pending == 0 &&
-                  ISC_LIST_EMPTY(fctx->validators)) {
+                  fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) {
                bucketnum = fctx->bucketnum;
                LOCK(&res->buckets[bucketnum].lock);
                /*
@@ -2550,8 +2560,8 @@ fctx_destroy(fetchctx_t *fctx) {
        REQUIRE(ISC_LIST_EMPTY(fctx->finds));
        REQUIRE(ISC_LIST_EMPTY(fctx->altfinds));
        REQUIRE(fctx->pending == 0);
-       REQUIRE(ISC_LIST_EMPTY(fctx->validators));
        REQUIRE(fctx->references == 0);
+       REQUIRE(ISC_LIST_EMPTY(fctx->validators));
 
        FCTXTRACE("destroy");
 
@@ -2741,7 +2751,7 @@ fctx_doshutdown(isc_task_t *task, isc_event_t *event) {
        }
 
        if (fctx->references == 0 && fctx->pending == 0 &&
-           ISC_LIST_EMPTY(fctx->validators))
+           fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators))
                bucket_empty = fctx_destroy(fctx);
 
        UNLOCK(&res->buckets[bucketnum].lock);
@@ -2782,6 +2792,7 @@ fctx_start(isc_task_t *task, isc_event_t *event) {
                 * pending ADB finds and no pending validations.
                 */
                INSIST(fctx->pending == 0);
+               INSIST(fctx->nqueries == 0);
                INSIST(ISC_LIST_EMPTY(fctx->validators));
                if (fctx->references == 0) {
                        /*
@@ -2948,6 +2959,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
        fctx->timeouts = 0;
        fctx->attributes = 0;
        fctx->spilled = ISC_FALSE;
+       fctx->nqueries = 0;
 
        dns_name_init(&fctx->nsname, NULL);
        fctx->nsfetch = NULL;
@@ -3281,7 +3293,8 @@ maybe_destroy(fetchctx_t *fctx) {
 
        REQUIRE(SHUTTINGDOWN(fctx));
 
-       if (fctx->pending != 0 || !ISC_LIST_EMPTY(fctx->validators))
+       if (fctx->pending != 0 || fctx->nqueries != 0 ||
+           !ISC_LIST_EMPTY(fctx->validators))
                return;
 
        bucketnum = fctx->bucketnum;
@@ -6728,7 +6741,8 @@ dns_resolver_destroyfetch(dns_fetch_t **fetchp) {
                /*
                 * No one cares about the result of this fetch anymore.
                 */
-               if (fctx->pending == 0 && ISC_LIST_EMPTY(fctx->validators) &&
+               if (fctx->pending == 0 && fctx->nqueries == 0 &&
+                   ISC_LIST_EMPTY(fctx->validators) &&
                    SHUTTINGDOWN(fctx)) {
                        /*
                         * This fctx is already shutdown; we were just
index 0e7d5b046854f6cd8e85ca938594fabdd243fe24..921ff7ef94843da049d38492df54e6b818467f63 100644 (file)
@@ -1,6 +1,6 @@
 #!/usr/local/bin/perl -w
 #
-# Copyright (C) 2004, 2005  Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2006  Internet Systems Consortium, Inc. ("ISC")
 # Copyright (C) 1998-2001  Internet Software Consortium.
 #
 # Permission to use, copy, modify, and distribute this software for any
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: update_copyrights,v 1.32.18.9 2005/09/06 01:59:47 marka Exp $
+# $Id: update_copyrights,v 1.32.18.10 2007/01/08 00:45:12 marka Exp $
 
 require 5.002;
 
 # Map copyright owners to the files containing copyright messages.
 # The first line of the copyright message is not in the file;
 # it is constructed by this script.
+#
+# Usage:
+#
+#   perl util/update_copyrights <util/copyrights
 
 my %owner2filename = (
        "" => "util/COPYRIGHT",
@@ -102,6 +106,7 @@ foreach $file (keys %file_types) {
                 print "$file: missing\n";
                 next;
         }
+       # print "Doing: $file";
 
         if ($years_list =~ /PARENT:/) {
                getyears($years_list);
@@ -150,7 +155,7 @@ foreach $file (keys %file_types) {
                 $start_comment = "/*\n";
                 $prefix = " * ";
                 $end_comment = " */\n";
-        } elsif ($type =~ /^(SH|PERL|TCL|MAKE|CONF-SH)$/) {
+        } elsif ($type =~ /^(SH|PERL|TCL|MAKE|CONF-SH|RNC)$/) {
                 $shell_comment = 1;
                 $prefix = "# ";
         } elsif ($type eq "ZONE" || $type eq "MC") {
@@ -241,10 +246,16 @@ foreach $file (keys %file_types) {
                         }
                 }
         } elsif ($sgml_comment) {
-                if (/^<!DOCTYPE/) {
-                        $before_copyright = $_;
-                        $_ = <SOURCE>;
-                               ;
+               $before_copyright = "";
+                while (/^<!DOCTYPE/ || /^<\?xml-stylesheet/ || /^<\?xml /) {
+                       # print "SGML: $_";
+                       $before_copyright = "$before_copyright$_";
+                       if (/>$/ ) {
+                               $_ = <SOURCE>;
+                               close(SOURCE) if (eof(SOURCE));
+                               next;
+                       }
+                       $_ = <SOURCE>;
                        while (!eof(SOURCE) && ! /^<!/ ) {
                                $before_copyright = "$before_copyright$_";
                                $_ = <SOURCE>;
@@ -423,6 +434,11 @@ foreach $file (keys %file_types) {
                 $_ = <SOURCE>;
                 $/ = "\n";
 
+               if ($type eq 'SGML' && m:<articleinfo>.*?</articleinfo>:s) {
+                       # print "docinfo: $file\n";
+                       my $r = copyrights(@years);
+                       s:<articleinfo>.*?</articleinfo>:<articleinfo>\n$r  </articleinfo>:s;
+               }
                if ($type eq 'SGML' && m:<docinfo>.*?</docinfo>:s) {
                        # print "docinfo: $file\n";
                        my $r = copyrights(@years);