~ubuntu-branches/ubuntu/hardy/bind9/hardy-updates

« back to all changes in this revision

Viewing changes to bin/named/query.c

  • Committer: Bazaar Package Importer
  • Author(s): Marc Deslauriers
  • Date: 2009-12-04 09:13:41 UTC
  • mfrom: (27.1.3 hardy-security)
  • Revision ID: james.westby@ubuntu.com-20091204091341-bjrdtj2upkihyq5z
Tags: 1:9.4.2.dfsg.P2-2ubuntu0.4
* SECURITY UPDATE: incorrect cache update from additional section
  - bin/named/query.c, lib/dns/{include/dns/types.h,masterdump.c,
    rbtdb.c,resolver.c,validator.c}: handle the additional section
    properly. lib/dns/api, version: increment versions.
  - debian/*: increment to libdns36, add libdns35 metapackage so
    upgrade-manager won't hold the bind9 upgrade back.
  - CVE-2009-4022

Show diffs side-by-side

added added

removed removed

Lines of Context:
109
109
#define DNS_GETDB_NOLOG 0x02U
110
110
#define DNS_GETDB_PARTIAL 0x04U
111
111
 
 
112
#define PENDINGOK(x)    (((x) & DNS_DBFIND_PENDINGOK) != 0)
 
113
 
112
114
typedef struct client_additionalctx {
113
115
        ns_client_t *client;
114
116
        dns_rdataset_t *rdataset;
1721
1723
         */
1722
1724
        if (result == ISC_R_SUCCESS &&
1723
1725
            additionaltype == dns_rdatasetadditional_fromcache &&
1724
 
            (rdataset->trust == dns_trust_pending ||
1725
 
             rdataset->trust == dns_trust_glue) &&
 
1726
            (DNS_TRUST_PENDING(rdataset->trust) ||
 
1727
             DNS_TRUST_GLUE(rdataset->trust)) &&
1726
1728
            !validate(client, db, fname, rdataset, sigrdataset)) {
1727
1729
                dns_rdataset_disassociate(rdataset);
1728
1730
                if (dns_rdataset_isassociated(sigrdataset))
1761
1763
         */
1762
1764
        if (result == ISC_R_SUCCESS &&
1763
1765
            additionaltype == dns_rdatasetadditional_fromcache &&
1764
 
            (rdataset->trust == dns_trust_pending ||
1765
 
             rdataset->trust == dns_trust_glue) &&
 
1766
            (DNS_TRUST_PENDING(rdataset->trust) ||
 
1767
             DNS_TRUST_GLUE(rdataset->trust)) &&
1766
1768
            !validate(client, db, fname, rdataset, sigrdataset)) {
1767
1769
                dns_rdataset_disassociate(rdataset);
1768
1770
                if (dns_rdataset_isassociated(sigrdataset))
2547
2549
        /*
2548
2550
         * Attempt to validate RRsets that are pending or that are glue.
2549
2551
         */
2550
 
        if ((rdataset->trust == dns_trust_pending ||
2551
 
             (sigrdataset != NULL && sigrdataset->trust == dns_trust_pending))
 
2552
        if ((DNS_TRUST_PENDING(rdataset->trust) ||
 
2553
             (sigrdataset != NULL && DNS_TRUST_PENDING(sigrdataset->trust)))
2552
2554
            && !validate(client, db, fname, rdataset, sigrdataset) &&
2553
 
            (client->query.dboptions & DNS_DBFIND_PENDINGOK) == 0)
 
2555
            !PENDINGOK(client->query.dboptions))
2554
2556
                goto cleanup;
2555
2557
 
2556
 
        if ((rdataset->trust == dns_trust_glue ||
2557
 
             (sigrdataset != NULL && sigrdataset->trust == dns_trust_glue)) &&
 
2558
        if ((DNS_TRUST_GLUE(rdataset->trust) ||
 
2559
             (sigrdataset != NULL && DNS_TRUST_GLUE(sigrdataset->trust))) &&
2558
2560
            !validate(client, db, fname, rdataset, sigrdataset) &&
2559
2561
            SECURE(client) && WANTDNSSEC(client))
2560
2562
                goto cleanup;
3335
3337
        unsigned int options;
3336
3338
        isc_boolean_t empty_wild;
3337
3339
        dns_rdataset_t *noqname;
 
3340
        dns_rdataset_t tmprdataset;
 
3341
        unsigned int dboptions;
3338
3342
 
3339
3343
        CTRACE("query_find");
3340
3344
 
3544
3548
        /*
3545
3549
         * Now look for an answer in the database.
3546
3550
         */
 
3551
        dboptions = client->query.dboptions;
 
3552
        if (sigrdataset == NULL && client->view->enablednssec) {
 
3553
                /*
 
3554
                 * If the client doesn't want DNSSEC we still want to
 
3555
                 * look for any data pending validation to save a remote
 
3556
                 * lookup if possible.
 
3557
                 */
 
3558
                dns_rdataset_init(&tmprdataset);
 
3559
                sigrdataset = &tmprdataset;
 
3560
                dboptions |= DNS_DBFIND_PENDINGOK;
 
3561
        }
 
3562
 refind:
3547
3563
        result = dns_db_find(db, client->query.qname, version, type,
3548
 
                             client->query.dboptions, client->now,
3549
 
                             &node, fname, rdataset, sigrdataset);
 
3564
                             dboptions, client->now, &node, fname,
 
3565
                             rdataset, sigrdataset);
 
3566
        /*
 
3567
         * If we have found pending data try to validate it.
 
3568
         * If the data does not validate as secure and we can't
 
3569
         * use the unvalidated data requery the database with
 
3570
         * pending disabled to prevent infinite looping.
 
3571
         */
 
3572
        if (result != ISC_R_SUCCESS || !DNS_TRUST_PENDING(rdataset->trust))
 
3573
                goto validation_done;
 
3574
        if (validate(client, db, fname, rdataset, sigrdataset))
 
3575
                goto validation_done;
 
3576
        if (rdataset->trust != dns_trust_pending_answer ||
 
3577
            !PENDINGOK(client->query.dboptions)) {
 
3578
                dns_rdataset_disassociate(rdataset);
 
3579
                if (sigrdataset != NULL &&
 
3580
                    dns_rdataset_isassociated(sigrdataset))
 
3581
                        dns_rdataset_disassociate(sigrdataset);
 
3582
                if (sigrdataset == &tmprdataset)
 
3583
                        sigrdataset = NULL;
 
3584
                dns_db_detachnode(db, &node);
 
3585
                dboptions &= ~DNS_DBFIND_PENDINGOK;
 
3586
                goto refind;
 
3587
        }
 
3588
 validation_done:
 
3589
        if (sigrdataset == &tmprdataset) {
 
3590
                if (dns_rdataset_isassociated(sigrdataset))
 
3591
                        dns_rdataset_disassociate(sigrdataset);
 
3592
                sigrdataset = NULL;
 
3593
        }
3550
3594
 
3551
3595
 resume:
3552
3596
        CTRACE("query_find: resume");