--- 9.7.3-P2 released ---
+3124. [bug] Use an rdataset attribute flag to indicate
+ negative-cache records rather than using rrtype 0;
+ this will prevent problems when that rrtype is
+ used in actual DNS packets. [RT #24777]
+
3123. [security] Change #2912 exposed a latent flaw in
dns_rdataset_totext() that could cause named to
crash with an assertion failure. [RT #24777]
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdataset.h,v 1.67.186.2.48.2 2011/06/06 23:46:32 tbox Exp $ */
+/* $Id: rdataset.h,v 1.67.186.2.48.3 2011/06/21 20:14:48 each Exp $ */
#ifndef DNS_RDATASET_H
#define DNS_RDATASET_H 1
#define DNS_RDATASETATTR_RESIGN 0x00040000
#define DNS_RDATASETATTR_CLOSEST 0x00080000
#define DNS_RDATASETATTR_OPTOUT 0x00100000 /*%< OPTOUT proof */
+#define DNS_RDATASETATTR_NEGATIVE 0x00200000
/*%
* _OMITDNSSEC:
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: masterdump.c,v 1.99.334.2 2011/06/06 23:46:31 tbox Exp $ */
+/* $Id: masterdump.c,v 1.99.334.3 2011/06/21 20:14:46 each Exp $ */
/*! \file */
isc_uint32_t current_ttl;
isc_boolean_t current_ttl_valid;
dns_rdatatype_t type;
+ unsigned int type_start;
REQUIRE(DNS_RDATASET_VALID(rdataset));
* Type.
*/
- if (rdataset->type == 0) {
+ if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
type = rdataset->covers;
} else {
type = rdataset->type;
}
- {
- unsigned int type_start;
- INDENT_TO(type_column);
- type_start = target->used;
- if (rdataset->type == 0)
- RETERR(str_totext("\\-", target));
- result = dns_rdatatype_totext(type, target);
- if (result != ISC_R_SUCCESS)
- return (result);
- column += (target->used - type_start);
- }
+ INDENT_TO(type_column);
+ type_start = target->used;
+ if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
+ RETERR(str_totext("\\-", target));
+ result = dns_rdatatype_totext(type, target);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ column += (target->used - type_start);
/*
* Rdata.
*/
INDENT_TO(rdata_column);
- if (rdataset->type == 0) {
+ if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
if (NXDOMAIN(rdataset))
RETERR(str_totext(";-$NXDOMAIN\n", target));
else
if (ctx->style.flags & DNS_STYLEFLAG_TRUST) {
fprintf(f, "; %s\n", dns_trust_totext(rds->trust));
}
- if (rds->type == 0 &&
+ if (((rds->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) &&
(ctx->style.flags & DNS_STYLEFLAG_NCACHE) == 0) {
/* Omit negative cache entries */
} else {
dns_rdataset_init(&rdataset);
dns_rdatasetiter_current(rdsiter, &rdataset);
- if (rdataset.type == 0 &&
+ if (((rdataset.attributes & DNS_RDATASETATTR_NEGATIVE) != 0) &&
(ctx->style.flags & DNS_STYLEFLAG_NCACHE) == 0) {
/* Omit negative cache entries */
} else {
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: message.c,v 1.249.10.4.36.2 2011/06/08 23:46:55 tbox Exp $ */
+/* $Id: message.c,v 1.249.10.4.36.3 2011/06/21 20:14:46 each Exp $ */
/*! \file */
isc_result_t
dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section) {
- unsigned int first_section;
+ unsigned int clear_after;
isc_result_t result;
REQUIRE(DNS_MESSAGE_VALID(msg));
msg->opcode != dns_opcode_notify)
want_question_section = ISC_FALSE;
if (msg->opcode == dns_opcode_update)
- first_section = DNS_SECTION_PREREQUISITE;
+ clear_after = DNS_SECTION_PREREQUISITE;
else if (want_question_section) {
if (!msg->question_ok)
return (DNS_R_FORMERR);
- first_section = DNS_SECTION_ANSWER;
+ clear_after = DNS_SECTION_ANSWER;
} else
- first_section = DNS_SECTION_QUESTION;
+ clear_after = DNS_SECTION_QUESTION;
msg->from_to_wire = DNS_MESSAGE_INTENTRENDER;
- msgresetnames(msg, first_section);
+ msgresetnames(msg, clear_after);
msgresetopt(msg);
msgresetsigs(msg, ISC_TRUE);
msginitprivate(msg);
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ncache.c,v 1.43.268.7.46.2 2011/06/06 23:46:32 tbox Exp $ */
+/* $Id: ncache.c,v 1.43.268.7.46.3 2011/06/21 20:14:46 each Exp $ */
/*! \file */
RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset)
== ISC_R_SUCCESS);
ncrdataset.trust = trust;
+ ncrdataset.attributes |= DNS_RDATASETATTR_NEGATIVE;
if (message->rcode == dns_rcode_nxdomain)
ncrdataset.attributes |= DNS_RDATASETATTR_NXDOMAIN;
if (optout)
REQUIRE(rdataset != NULL);
REQUIRE(rdataset->type == 0);
+ REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
savedbuffer = *target;
count = 0;
REQUIRE(ncacherdataset != NULL);
REQUIRE(ncacherdataset->type == 0);
+ REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
REQUIRE(name != NULL);
REQUIRE(!dns_rdataset_isassociated(rdataset));
REQUIRE(type != dns_rdatatype_rrsig);
REQUIRE(ncacherdataset != NULL);
REQUIRE(ncacherdataset->type == 0);
+ REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
REQUIRE(name != NULL);
REQUIRE(!dns_rdataset_isassociated(rdataset));
REQUIRE(ncacherdataset != NULL);
REQUIRE(ncacherdataset->type == 0);
+ REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
REQUIRE(found != NULL);
REQUIRE(!dns_rdataset_isassociated(rdataset));
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsec3.c,v 1.13.6.6 2010/12/07 03:01:40 marka Exp $ */
+/* $Id: nsec3.c,v 1.13.6.6.12.1 2011/06/21 20:14:47 each Exp $ */
#include <config.h>
isc_result_t
dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
- dns_rdatatype_t type, dns_diff_t *diff)
+ dns_rdatatype_t privatetype, dns_diff_t *diff)
{
dns_dbnode_t *node = NULL;
dns_rdata_nsec3param_t nsec3param;
dns_rdataset_disassociate(&rdataset);
try_private:
- if (type == 0)
+ if (privatetype == 0)
goto success;
- result = dns_db_findrdataset(db, node, version, type, 0, 0,
+ result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
&rdataset, NULL);
if (result == ISC_R_NOTFOUND)
goto success;
isc_result_t
dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version,
- isc_boolean_t complete, dns_rdatatype_t type,
+ isc_boolean_t complete, dns_rdatatype_t privatetype,
isc_boolean_t *answer)
{
dns_dbnode_t *node = NULL;
*answer = ISC_FALSE;
try_private:
- if (type == 0 || complete) {
+ if (privatetype == 0 || complete) {
*answer = ISC_FALSE;
return (ISC_R_SUCCESS);
}
- result = dns_db_findrdataset(db, node, version, type, 0, 0,
+ result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
&rdataset, NULL);
dns_db_detachnode(db, &node);
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbtdb.c,v 1.292.8.15 2010/12/02 05:07:03 marka Exp $ */
+/* $Id: rbtdb.c,v 1.292.8.15.10.1 2011/06/21 20:14:47 each Exp $ */
/*! \file */
#define RDATASET_ATTR_RESIGN 0x0020
#define RDATASET_ATTR_STATCOUNT 0x0040
#define RDATASET_ATTR_OPTOUT 0x0080
+#define RDATASET_ATTR_NEGATIVE 0x0100
typedef struct acache_cbarg {
dns_rdatasetadditional_t type;
(((header)->attributes & RDATASET_ATTR_RESIGN) != 0)
#define OPTOUT(header) \
(((header)->attributes & RDATASET_ATTR_OPTOUT) != 0)
+#define NEGATIVE(header) \
+ (((header)->attributes & RDATASET_ATTR_NEGATIVE) != 0)
#define DEFAULT_NODE_LOCK_COUNT 7 /*%< Should be prime. */
/* At the moment we count statistics only for cache DB */
INSIST(IS_CACHE(rbtdb));
- if (NXDOMAIN(header))
- statattributes = DNS_RDATASTATSTYPE_ATTR_NXDOMAIN;
- else if (RBTDB_RDATATYPE_BASE(header->type) == 0) {
- statattributes = DNS_RDATASTATSTYPE_ATTR_NXRRSET;
- base = RBTDB_RDATATYPE_EXT(header->type);
+ if (NEGATIVE(header)) {
+ if (NXDOMAIN(header))
+ statattributes = DNS_RDATASTATSTYPE_ATTR_NXDOMAIN;
+ else {
+ statattributes = DNS_RDATASTATSTYPE_ATTR_NXRRSET;
+ base = RBTDB_RDATATYPE_EXT(header->type);
+ }
} else
base = RBTDB_RDATATYPE_BASE(header->type);
rdataset->covers = RBTDB_RDATATYPE_EXT(header->type);
rdataset->ttl = header->rdh_ttl - now;
rdataset->trust = header->trust;
+ if (NEGATIVE(header))
+ rdataset->attributes |= DNS_RDATASETATTR_NEGATIVE;
if (NXDOMAIN(header))
rdataset->attributes |= DNS_RDATASETATTR_NXDOMAIN;
if (OPTOUT(header))
*nodep = node;
}
- if (RBTDB_RDATATYPE_BASE(found->type) == 0) {
+ if (NEGATIVE(found)) {
/*
* We found a negative cache entry.
*/
if (found == NULL)
return (ISC_R_NOTFOUND);
- if (RBTDB_RDATATYPE_BASE(found->type) == 0) {
+ if (NEGATIVE(found)) {
/*
* We found a negative cache entry.
*/
negtype = 0;
if (rbtversion == NULL && !newheader_nx) {
rdtype = RBTDB_RDATATYPE_BASE(newheader->type);
- if (rdtype == 0) {
+ if (NEGATIVE(newheader)) {
/*
* We're adding a negative cache entry.
*/
} else {
newheader->serial = 1;
newheader->resign = 0;
+ if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
+ newheader->attributes |= RDATASET_ATTR_NEGATIVE;
if ((rdataset->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
newheader->attributes |= RDATASET_ATTR_NXDOMAIN;
if ((rdataset->attributes & DNS_RDATASETATTR_OPTOUT) != 0)
type = header->type;
rdtype = RBTDB_RDATATYPE_BASE(header->type);
- if (rdtype == 0) {
+ if (NEGATIVE(header)) {
covers = RBTDB_RDATATYPE_EXT(header->type);
negtype = RBTDB_RDATATYPE_VALUE(covers, 0);
} else
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdataset.c,v 1.84.186.2.48.2 2011/06/06 23:46:32 tbox Exp $ */
+/* $Id: rdataset.c,v 1.84.186.2.48.3 2011/06/21 20:14:47 each Exp $ */
/*! \file */
count = 1;
result = dns_rdataset_first(rdataset);
INSIST(result == ISC_R_NOMORE);
- } else if (rdataset->type == 0) {
+ } else if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
/*
* This is a negative caching rdataset.
*/
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.c,v 1.413.14.15 2011/01/27 23:46:37 tbox Exp $ */
+/* $Id: resolver.c,v 1.413.14.15.12.1 2011/06/21 20:14:47 each Exp $ */
/*! \file */
FCTX_ADDRINFO_TRIED) != 0)
#define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
+#define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
static void destroy(dns_resolver_t *res);
static void empty_bucket(dns_resolver_t *res);
* Negative results must be indicated in event->result.
*/
if (dns_rdataset_isassociated(event->rdataset) &&
- event->rdataset->type == dns_rdatatype_none) {
+ NEGATIVE(event->rdataset)) {
INSIST(event->result == DNS_R_NCACHENXDOMAIN ||
event->result == DNS_R_NCACHENXRRSET);
}
if (result != ISC_R_SUCCESS &&
result != DNS_R_UNCHANGED)
goto noanswer_response;
- if (ardataset != NULL && ardataset->type == 0) {
+ if (ardataset != NULL && NEGATIVE(ardataset)) {
if (NXDOMAIN(ardataset))
eresult = DNS_R_NCACHENXDOMAIN;
else
result = ISC_R_SUCCESS;
if (!need_validation &&
ardataset != NULL &&
- ardataset->type == 0) {
+ NEGATIVE(ardataset)) {
/*
* The answer in the cache is
* better than the answer we
if (result == DNS_R_UNCHANGED) {
if (ANSWER(rdataset) &&
ardataset != NULL &&
- ardataset->type == 0) {
+ NEGATIVE(ardataset)) {
/*
* The answer in the cache is better
* than the answer we found, and is
* Negative results must be indicated in event->result.
*/
if (dns_rdataset_isassociated(event->rdataset) &&
- event->rdataset->type == dns_rdatatype_none) {
+ NEGATIVE(event->rdataset)) {
INSIST(eresult == DNS_R_NCACHENXDOMAIN ||
eresult == DNS_R_NCACHENXRRSET);
}
* care about whether it is DNS_R_NCACHENXDOMAIN or
* DNS_R_NCACHENXRRSET then extract it.
*/
- if (ardataset->type == 0) {
+ if (NEGATIVE(ardataset)) {
/*
* The cache data is a negative cache entry.
*/
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: validator.c,v 1.182.16.14.10.2 2011/06/06 23:46:32 tbox Exp $ */
+/* $Id: validator.c,v 1.182.16.14.10.3 2011/06/21 20:14:47 each Exp $ */
#include <config.h>
#define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0)
#define CANCELED(v) (((v)->attributes & VALATTR_CANCELED) != 0)
+#define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
+
static void
destroy(dns_validator_t *val);
name = dns_fixedname_name(&val->fname);
if ((val->attributes & VALATTR_INSECURITY) != 0 &&
val->frdataset.covers == dns_rdatatype_ds &&
- val->frdataset.type == 0 &&
+ NEGATIVE(&val->frdataset) &&
isdelegation(name, &val->frdataset, DNS_R_NCACHENXRRSET)) {
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
val->attributes |= VALATTR_NEEDNODATA;
result = nsecvalidate(val, ISC_FALSE);
} else if (val->event->rdataset != NULL &&
- val->event->rdataset->type == 0)
+ NEGATIVE(val->event->rdataset))
{
/*
* This is a nonexistence validation.