diff --git a/CHANGES b/CHANGES index 17697ac3cd..0e62743e38 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ + 60. [func] Catch and disallow singleton types on message + parse. + 59. [bug] Cause net/host unreachable to be a hard error when sending and receiving. diff --git a/lib/dns/include/dns/rdata.h b/lib/dns/include/dns/rdata.h index fb572b2176..a4c64a7329 100644 --- a/lib/dns/include/dns/rdata.h +++ b/lib/dns/include/dns/rdata.h @@ -439,6 +439,16 @@ isc_boolean_t dns_rdatatype_ismeta(dns_rdatatype_t type); * */ +isc_boolean_t dns_rdatatype_issingleton(dns_rdatatype_t type); +/* + * Return true iff the rdata type 'type' is a singleton type, + * like CNAME or SOA. + * + * Requires: + * 'type' is a valid rdata type. + * + */ + isc_boolean_t dns_rdataclass_ismeta(dns_rdataclass_t rdclass); /* * Return true iff the rdata class 'rdclass' is a meta-class diff --git a/lib/dns/message.c b/lib/dns/message.c index fe82d8873f..0a2c952749 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -1196,11 +1196,19 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, * append this rdata to that set. If we did not, we need * to create a new rdatalist, store the important bits there, * convert it to an rdataset, and link the latter to the name. - * Yuck. + * Yuck. When appending, make certain that the type isn't + * a singleton type, such as SOA or CNAME. * - * XXXRTH Check for attempts to create multi-record RRsets - * for singleton RR types. + * Note that this check will be bypassed when preserving order, + * the opcode is an update, or the type search is skipped. */ + if (result == ISC_R_SUCCESS) { + if (dns_rdatatype_issingleton(rdtype)) { + result = DNS_R_FORMERR; + goto cleanup; + } + } + if (result == ISC_R_NOTFOUND) { rdataset = isc_mempool_get(msg->rdspool); if (rdataset == NULL) { diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c index 98a4b705fa..66bd3309da 100644 --- a/lib/dns/rdata.c +++ b/lib/dns/rdata.c @@ -15,7 +15,7 @@ * SOFTWARE. */ -/* $Id: rdata.c,v 1.75 2000/04/14 17:28:21 bwelling Exp $ */ +/* $Id: rdata.c,v 1.76 2000/04/14 18:36:00 explorer Exp $ */ #include @@ -1548,12 +1548,14 @@ fromtext_error(void (*callback)(dns_rdatacallbacks_t *, char *, ...), } dns_rdatatype_t -dns_rdata_covers(dns_rdata_t *rdata) { +dns_rdata_covers(dns_rdata_t *rdata) +{ return (covers_sig(rdata)); } static isc_boolean_t -ismeta(unsigned int code, struct tbl *table) { +ismeta(unsigned int code, struct tbl *table) +{ struct tbl *t; REQUIRE(code < 65536); for (t = table; t->name != NULL; t++) { @@ -1564,14 +1566,25 @@ ismeta(unsigned int code, struct tbl *table) { } isc_boolean_t -dns_rdatatype_ismeta(dns_rdatatype_t type) { +dns_rdatatype_ismeta(dns_rdatatype_t type) +{ if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_META) != 0) return (ISC_TRUE); return (ISC_FALSE); } isc_boolean_t -dns_rdataclass_ismeta(dns_rdataclass_t rdclass) { +dns_rdatatype_issingleton(dns_rdatatype_t type) +{ + if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_SINGLETON) + != 0) + return (ISC_TRUE); + return (ISC_FALSE); +} + +isc_boolean_t +dns_rdataclass_ismeta(dns_rdataclass_t rdclass) +{ return (ismeta(rdclass, classes)); }