ALT Linux repos
S: | 9.16.44-alt1 |
5.0: | 9.3.6-alt5 |
4.1: | 9.3.6-alt4.M41.2 |
+updates: | 9.3.6-alt4.M41.1 |
4.0: | 9.3.6-alt4.M41.1 |
+updates: | 9.3.6-alt4.M41.1 |
3.0: | 9.2.4.rel-alt2 |
Group :: System/Servers
RPM: bind
Main Changelog Spec Patches Sources Download Gear Bugs and FR Repocop
Patch: bind93-rh538744-CVE-2009-4022.patch
Download
Download
--- bind-9.3.6-P1/bin/named/query.c.rh538744 2009-11-19 15:01:05.922165541 +0100
+++ bind-9.3.6-P1/bin/named/query.c 2009-11-19 15:02:31.422164887 +0100
@@ -92,6 +92,8 @@
#define DNS_GETDB_NOLOG 0x02U
#define DNS_GETDB_PARTIAL 0x04U
+#define PENDINGOK(x) (((x) & DNS_DBFIND_PENDINGOK) != 0)
+
static void
query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype);
@@ -1698,14 +1700,14 @@ query_addbestns(ns_client_t *client) {
zsigrdataset = NULL;
}
- if ((client->query.dboptions & DNS_DBFIND_PENDINGOK) == 0 &&
- (rdataset->trust == dns_trust_pending ||
- (sigrdataset != NULL && sigrdataset->trust == dns_trust_pending)))
+ if (!PENDINGOK(client->query.dboptions) &&
+ (DNS_TRUST_PENDING(rdataset->trust) ||
+ (sigrdataset != NULL && DNS_TRUST_PENDING(sigrdataset->trust))))
goto cleanup;
if (WANTDNSSEC(client) && SECURE(client) &&
- (rdataset->trust == dns_trust_glue ||
- (sigrdataset != NULL && sigrdataset->trust == dns_trust_glue)))
+ (DNS_TRUST_GLUE(rdataset->trust) ||
+ (sigrdataset != NULL && DNS_TRUST_GLUE(sigrdataset->trust))))
goto cleanup;
query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf,
--- bind-9.3.6-P1/lib/dns/include/dns/types.h.rh538744 2009-11-19 15:01:05.942166028 +0100
+++ bind-9.3.6-P1/lib/dns/include/dns/types.h 2009-11-19 15:01:05.952166608 +0100
@@ -230,40 +230,52 @@ enum {
dns_trust_none = 0,
#define dns_trust_none ((dns_trust_t)dns_trust_none)
+ /*
+ * Subject to DNSSEC validation but has not yet been validated
+ * (from the additional section).
+ */
+ dns_trust_pending_additional = 1,
+#define dns_trust_pending_additional \
+ ((dns_trust_t)dns_trust_pending_additional)
+
/* Subject to DNSSEC validation but has not yet been validated */
- dns_trust_pending = 1,
-#define dns_trust_pending ((dns_trust_t)dns_trust_pending)
+ dns_trust_pending_answer = 2,
+#define dns_trust_pending ((dns_trust_t)dns_trust_pending_answer)
/* Received in the additional section of a response. */
- dns_trust_additional = 2,
+ dns_trust_additional = 3,
#define dns_trust_additional ((dns_trust_t)dns_trust_additional)
/* Received in a referral response. */
- dns_trust_glue = 3,
+ dns_trust_glue = 4,
#define dns_trust_glue ((dns_trust_t)dns_trust_glue)
/* Answser from a non-authoritative server */
- dns_trust_answer = 4,
+ dns_trust_answer = 5,
#define dns_trust_answer ((dns_trust_t)dns_trust_answer)
/* Received in the authority section as part of an
authoritative response */
- dns_trust_authauthority = 5,
+ dns_trust_authauthority = 6,
#define dns_trust_authauthority ((dns_trust_t)dns_trust_authauthority)
/* Answser from an authoritative server */
- dns_trust_authanswer = 6,
+ dns_trust_authanswer = 7,
#define dns_trust_authanswer ((dns_trust_t)dns_trust_authanswer)
/* Successfully DNSSEC validated */
- dns_trust_secure = 7,
+ dns_trust_secure = 8,
#define dns_trust_secure ((dns_trust_t)dns_trust_secure)
/* This server is authoritative */
- dns_trust_ultimate = 8
+ dns_trust_ultimate = 9
#define dns_trust_ultimate ((dns_trust_t)dns_trust_ultimate)
};
+#define DNS_TRUST_PENDING(x) ((x) == dns_trust_pending_answer || \
+ (x) == dns_trust_pending_additional)
+#define DNS_TRUST_GLUE(x) ((x) == dns_trust_glue)
+
/*
* Name checking severites.
*/
--- bind-9.3.6-P1/lib/dns/masterdump.c.rh538744 2008-08-14 01:45:33.000000000 +0200
+++ bind-9.3.6-P1/lib/dns/masterdump.c 2009-11-19 15:01:05.952166608 +0100
@@ -763,7 +763,8 @@ dump_order_compare(const void *a, const
static const char *trustnames[] = {
"none",
- "pending",
+ "pending-additional",
+ "pending-answer",
"additional",
"glue",
"answer",
--- bind-9.3.6-P1/lib/dns/rbtdb.c.rh538744 2008-01-25 00:45:27.000000000 +0100
+++ bind-9.3.6-P1/lib/dns/rbtdb.c 2009-11-19 15:01:05.952166608 +0100
@@ -2667,7 +2667,7 @@ cache_zonecut_callback(dns_rbtnode_t *no
}
if (dname_header != NULL &&
- (dname_header->trust != dns_trust_pending ||
+ (!DNS_TRUST_PENDING(dname_header->trust) ||
(search->options & DNS_DBFIND_PENDINGOK) != 0)) {
/*
* We increment the reference count on node to ensure that
@@ -3129,7 +3129,7 @@ cache_find(dns_db_t *db, dns_name_t *nam
if (found == NULL ||
(found->trust == dns_trust_glue &&
((options & DNS_DBFIND_GLUEOK) == 0)) ||
- (found->trust == dns_trust_pending &&
+ (DNS_TRUST_PENDING(found->trust) &&
((options & DNS_DBFIND_PENDINGOK) == 0))) {
/*
* If there is an NS rdataset at this node, then this is the
diff -u bind-9.3.6-P1/lib/dns/resolver.c bind-9.3.6-P1/lib/dns/resolver.c
--- bind-9.3.6-P1/lib/dns/resolver.c 2009-11-19 15:01:05.952166608 +0100
+++ bind-9.3.6-P1/lib/dns/resolver.c 2010-01-18 15:34:58.835888666 +0100
@@ -3690,10 +3690,19 @@
rdataset->ttl = res->view->maxcachettl;
/*
- * If this rrset is in a secure domain, do DNSSEC validation
- * for it, unless it is glue.
+ * If this RRset is in a secure domain, is in bailiwick,
+ * and is not glue, attempt DNSSEC validation. (We do not
+ * attempt to validate glue or out-of-bailiwick data--even
+ * though there might be some performance benefit to doing
+ * so--because it makes it simpler and safer to ensure that
+ * records from a secure domain are only cached if validated
+ * within the context of a query to the domain that owns
+ * them.)
*/
- if (secure_domain && rdataset->trust != dns_trust_glue) {
+ if (secure_domain && rdataset->trust != dns_trust_glue &&
+ !EXTERNAL(rdataset)) {
+ dns_trust_t trust;
+
/*
* RRSIGs are validated as part of validating the
* type they cover.
@@ -3731,11 +3740,17 @@
/*
* Cache this rdataset/sigrdataset pair as
- * pending data.
+ * pending data. Track whether it was additional
+ * or not.
*/
- rdataset->trust = dns_trust_pending;
+ if (rdataset->trust == dns_trust_additional)
+ trust = dns_trust_pending_additional;
+ else
+ trust = dns_trust_pending_answer;
+
+ rdataset->trust = trust;
if (sigrdataset != NULL)
- sigrdataset->trust = dns_trust_pending;
+ sigrdataset->trust = trust;
if (!need_validation)
addedrdataset = ardataset;
else
@@ -4081,7 +4096,7 @@
for (trdataset = ISC_LIST_HEAD(tname->list);
trdataset != NULL;
trdataset = ISC_LIST_NEXT(trdataset, link))
- trdataset->trust = dns_trust_pending;
+ trdataset->trust = dns_trust_pending_answer;
result = dns_message_nextname(fctx->rmessage,
DNS_SECTION_AUTHORITY);
}
@@ -4826,9 +4841,7 @@
/*
* This data is outside of
* our query domain, and
- * may only be cached if it
- * comes from a secure zone
- * and validates.
+ * may not be cached.
*/
rdataset->attributes |=
DNS_RDATASETATTR_EXTERNAL;
--- bind-9.3.6-P1/lib/dns/validator.c.rh538744 2008-08-21 06:59:16.000000000 +0200
+++ bind-9.3.6-P1/lib/dns/validator.c 2009-11-19 15:01:06.142166214 +0100
@@ -1023,8 +1053,11 @@ create_fetch(dns_validator_t *val, dns_n
if (dns_rdataset_isassociated(&val->fsigrdataset))
dns_rdataset_disassociate(&val->fsigrdataset);
- if (check_deadlock(val, name, type))
+ if (check_deadlock(val, name, type)) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "deadlock found (create_fetch)");
return (DNS_R_NOVALIDSIG);
+ }
validator_logcreate(val, name, type, caller, "fetch");
return (dns_resolver_createfetch(val->view->resolver, name, type,
@@ -1046,8 +1079,11 @@ create_validator(dns_validator_t *val, d
{
isc_result_t result;
- if (check_deadlock(val, name, type))
+ if (check_deadlock(val, name, type)) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "deadlock found (create_validator)");
return (DNS_R_NOVALIDSIG);
+ }
validator_logcreate(val, name, type, caller, "validator");
result = dns_validator_create(val->view, name, type,
@@ -1176,7 +1212,7 @@ get_key(dns_validator_t *val, dns_rdata_
* We have an rrset for the given keyname.
*/
val->keyset = &val->frdataset;
- if (val->frdataset.trust == dns_trust_pending &&
+ if (DNS_TRUST_PENDING(val->frdataset.trust) &&
dns_rdataset_isassociated(&val->fsigrdataset))
{
/*
@@ -1191,7 +1227,7 @@ get_key(dns_validator_t *val, dns_rdata_
if (result != ISC_R_SUCCESS)
return (result);
return (DNS_R_WAIT);
- } else if (val->frdataset.trust == dns_trust_pending) {
+ } else if (DNS_TRUST_PENDING(val->frdataset.trust)) {
/*
* Having a pending key with no signature means that
* something is broken.
@@ -1729,10 +1765,15 @@ validatezonekey(dns_validator_t *val) {
* give up, since there's no DS at the root.
*/
if (dns_name_equal(event->name, dns_rootname)) {
- if ((val->attributes & VALATTR_TRIEDVERIFY) != 0)
+ if ((val->attributes & VALATTR_TRIEDVERIFY) != 0) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "root key failed to validate");
return (DNS_R_NOVALIDSIG);
- else
+ } else {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "no trusted root key");
return (DNS_R_NOVALIDDS);
+ }
}
if (atsep) {
@@ -1760,7 +1801,7 @@ validatezonekey(dns_validator_t *val) {
* We have DS records.
*/
val->dsset = &val->frdataset;
- if (val->frdataset.trust == dns_trust_pending &&
+ if (DNS_TRUST_PENDING(val->frdataset.trust) &&
dns_rdataset_isassociated(&val->fsigrdataset))
{
result = create_validator(val,
@@ -1773,7 +1814,7 @@ validatezonekey(dns_validator_t *val) {
if (result != ISC_R_SUCCESS)
return (result);
return (DNS_R_WAIT);
- } else if (val->frdataset.trust == dns_trust_pending) {
+ } else if (DNS_TRUST_PENDING(val->frdataset.trust)) {
/*
* There should never be an unsigned DS.
*/
@@ -1934,8 +1975,11 @@ validatezonekey(dns_validator_t *val) {
"no supported algorithm/digest (DS)");
markanswer(val);
return (ISC_R_SUCCESS);
- } else
+ } else {
+ validator_log(val, ISC_LOG_INFO,
+ "no valid signature found (DS)");
return (DNS_R_NOVALIDSIG);
+ }
}
/*%
@@ -2408,8 +2476,11 @@ finddlvsep(dns_validator_t *val, isc_boo
namebuf);
result = view_find(val, dlvname, dns_rdatatype_dlv);
if (result == ISC_R_SUCCESS) {
- if (val->frdataset.trust < dns_trust_secure)
+ if (val->frdataset.trust < dns_trust_secure) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "DLV not validated");
return (DNS_R_NOVALIDSIG);
+ }
val->havedlvsep = ISC_TRUE;
dns_rdataset_clone(&val->frdataset, &val->dlv);
return (ISC_R_SUCCESS);
@@ -2523,7 +2594,8 @@ proveunsecure(dns_validator_t *val, isc_
if ((val->view->dlv == NULL || DLVTRIED(val)) &&
val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure at '%s'",
+ "must be secure failure at '%s', "
+ "can't fall back to DLV",
namebuf);
result = DNS_R_MUSTBESECURE;
goto out;
@@ -2568,7 +2640,7 @@ proveunsecure(dns_validator_t *val, isc_
* There is no DS. If this is a delegation,
* we maybe done.
*/
- if (val->frdataset.trust == dns_trust_pending) {
+ if (DNS_TRUST_PENDING(val->frdataset.trust)) {
result = create_fetch(val, tname,
dns_rdatatype_ds,
dsfetched2,
@@ -2584,6 +2656,9 @@ proveunsecure(dns_validator_t *val, isc_
* there's no way of validating existing
* negative response blobs, give up.
*/
+ validator_log(val, ISC_LOG_WARNING,
+ "can't validate existing "
+ "negative responses (no DS)");
result = DNS_R_NOVALIDSIG;
goto out;
}
@@ -2630,6 +2705,8 @@ proveunsecure(dns_validator_t *val, isc_
}
else if (!dns_rdataset_isassociated(&val->fsigrdataset))
{
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "DS is unsigned");
result = DNS_R_NOVALIDSIG;
goto out;
}
@@ -2661,6 +2738,10 @@ proveunsecure(dns_validator_t *val, isc_
* there's no way of validating existing
* negative response blobs, give up.
*/
+ validator_log(val, ISC_LOG_WARNING,
+ "can't validate existing "
+ "negative responses "
+ "(not a zone cut)");
result = DNS_R_NOVALIDSIG;
goto out;
}