fix CVE-2023-4408 CVE-2023-5517 CVE-2023-5679 CVE-2023-50387 CVE-2023-50868
(cherry picked from commit ab8deb433bf4516aeaf7fa5e386c6d91766c8cfe)
This commit is contained in:
parent
ed53d67d48
commit
1ade067ea8
901
backport-CVE-2023-4408.patch
Normal file
901
backport-CVE-2023-4408.patch
Normal file
@ -0,0 +1,901 @@
|
|||||||
|
From 608707b4f5b473e416563bfe0d43e26d6dc4a5c6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
|
||||||
|
Date: Mon, 11 Sep 2023 10:35:28 +0200
|
||||||
|
Subject: [PATCH] Use hashtable when parsing a message
|
||||||
|
|
||||||
|
When parsing messages use a hashtable instead of a linear search to
|
||||||
|
reduce the amount of work done in findname when there's more than one
|
||||||
|
name in the section.
|
||||||
|
|
||||||
|
There are two hashtables:
|
||||||
|
|
||||||
|
1) hashtable for owner names - that's constructed for each section when
|
||||||
|
we hit the second name in the section and destroyed right after parsing
|
||||||
|
that section;
|
||||||
|
|
||||||
|
2) per-name hashtable - for each name in the section, we construct a new
|
||||||
|
hashtable for that name if there are more than one rdataset for that
|
||||||
|
particular name.
|
||||||
|
|
||||||
|
Conflict:NA
|
||||||
|
Reference:https://downloads.isc.org/isc/bind/9.18.24/patches/0001-CVE-2023-4408.patch
|
||||||
|
|
||||||
|
(cherry picked from commit b8a96317544c7b310b4f74360825a87b6402ddc2)
|
||||||
|
|
||||||
|
---
|
||||||
|
lib/dns/include/dns/message.h | 38 ----
|
||||||
|
lib/dns/include/dns/name.h | 37 ++--
|
||||||
|
lib/dns/message.c | 374 ++++++++++++++++++++++------------
|
||||||
|
lib/dns/name.c | 1 +
|
||||||
|
lib/isc/ht.c | 55 ++++-
|
||||||
|
5 files changed, 309 insertions(+), 196 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h
|
||||||
|
index 940c9b1..f15884a 100644
|
||||||
|
--- a/lib/dns/include/dns/message.h
|
||||||
|
+++ b/lib/dns/include/dns/message.h
|
||||||
|
@@ -856,44 +856,6 @@ dns_message_findtype(const dns_name_t *name, dns_rdatatype_t type,
|
||||||
|
*\li #ISC_R_NOTFOUND -- the desired type does not exist.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-isc_result_t
|
||||||
|
-dns_message_find(const dns_name_t *name, dns_rdataclass_t rdclass,
|
||||||
|
- dns_rdatatype_t type, dns_rdatatype_t covers,
|
||||||
|
- dns_rdataset_t **rdataset);
|
||||||
|
-/*%<
|
||||||
|
- * Search the name for the specified rdclass and type. If it is found,
|
||||||
|
- * *rdataset is filled in with a pointer to that rdataset.
|
||||||
|
- *
|
||||||
|
- * Requires:
|
||||||
|
- *\li if '**rdataset' is non-NULL, *rdataset needs to be NULL.
|
||||||
|
- *
|
||||||
|
- *\li 'type' be a valid type, and NOT dns_rdatatype_any.
|
||||||
|
- *
|
||||||
|
- *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
|
||||||
|
- * Otherwise it should be 0.
|
||||||
|
- *
|
||||||
|
- * Returns:
|
||||||
|
- *\li #ISC_R_SUCCESS -- all is well.
|
||||||
|
- *\li #ISC_R_NOTFOUND -- the desired type does not exist.
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
-void
|
||||||
|
-dns_message_movename(dns_message_t *msg, dns_name_t *name,
|
||||||
|
- dns_section_t fromsection, dns_section_t tosection);
|
||||||
|
-/*%<
|
||||||
|
- * Move a name from one section to another.
|
||||||
|
- *
|
||||||
|
- * Requires:
|
||||||
|
- *
|
||||||
|
- *\li 'msg' be valid.
|
||||||
|
- *
|
||||||
|
- *\li 'name' must be a name already in 'fromsection'.
|
||||||
|
- *
|
||||||
|
- *\li 'fromsection' must be a valid section.
|
||||||
|
- *
|
||||||
|
- *\li 'tosection' must be a valid section.
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
void
|
||||||
|
dns_message_addname(dns_message_t *msg, dns_name_t *name,
|
||||||
|
dns_section_t section);
|
||||||
|
diff --git a/lib/dns/include/dns/name.h b/lib/dns/include/dns/name.h
|
||||||
|
index a758c4d..199856a 100644
|
||||||
|
--- a/lib/dns/include/dns/name.h
|
||||||
|
+++ b/lib/dns/include/dns/name.h
|
||||||
|
@@ -68,6 +68,7 @@
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
+#include <isc/ht.h>
|
||||||
|
#include <isc/lang.h>
|
||||||
|
#include <isc/magic.h>
|
||||||
|
#include <isc/region.h> /* Required for storage size of dns_label_t. */
|
||||||
|
@@ -111,6 +112,7 @@ struct dns_name {
|
||||||
|
isc_buffer_t *buffer;
|
||||||
|
ISC_LINK(dns_name_t) link;
|
||||||
|
ISC_LIST(dns_rdataset_t) list;
|
||||||
|
+ isc_ht_t *ht;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DNS_NAME_MAGIC ISC_MAGIC('D', 'N', 'S', 'n')
|
||||||
|
@@ -166,30 +168,24 @@ extern const dns_name_t *dns_wildcardname;
|
||||||
|
* unsigned char offsets[] = { 0, 6 };
|
||||||
|
* dns_name_t value = DNS_NAME_INITABSOLUTE(data, offsets);
|
||||||
|
*/
|
||||||
|
-#define DNS_NAME_INITNONABSOLUTE(A, B) \
|
||||||
|
- { \
|
||||||
|
- DNS_NAME_MAGIC, A, (sizeof(A) - 1), sizeof(B), \
|
||||||
|
- DNS_NAMEATTR_READONLY, B, NULL, \
|
||||||
|
- { (void *)-1, (void *)-1 }, { \
|
||||||
|
- NULL, NULL \
|
||||||
|
- } \
|
||||||
|
+#define DNS_NAME_INITNONABSOLUTE(A, B) \
|
||||||
|
+ { \
|
||||||
|
+ DNS_NAME_MAGIC, A, (sizeof(A) - 1), sizeof(B), \
|
||||||
|
+ DNS_NAMEATTR_READONLY, B, NULL, \
|
||||||
|
+ { (void *)-1, (void *)-1 }, { NULL, NULL }, NULL \
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define DNS_NAME_INITABSOLUTE(A, B) \
|
||||||
|
- { \
|
||||||
|
- DNS_NAME_MAGIC, A, sizeof(A), sizeof(B), \
|
||||||
|
- DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, B, \
|
||||||
|
- NULL, { (void *)-1, (void *)-1 }, { \
|
||||||
|
- NULL, NULL \
|
||||||
|
- } \
|
||||||
|
+#define DNS_NAME_INITABSOLUTE(A, B) \
|
||||||
|
+ { \
|
||||||
|
+ DNS_NAME_MAGIC, A, sizeof(A), sizeof(B), \
|
||||||
|
+ DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, B, \
|
||||||
|
+ NULL, { (void *)-1, (void *)-1 }, { NULL, NULL }, NULL \
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define DNS_NAME_INITEMPTY \
|
||||||
|
- { \
|
||||||
|
- DNS_NAME_MAGIC, NULL, 0, 0, 0, NULL, NULL, \
|
||||||
|
- { (void *)-1, (void *)-1 }, { \
|
||||||
|
- NULL, NULL \
|
||||||
|
- } \
|
||||||
|
+#define DNS_NAME_INITEMPTY \
|
||||||
|
+ { \
|
||||||
|
+ DNS_NAME_MAGIC, NULL, 0, 0, 0, NULL, NULL, \
|
||||||
|
+ { (void *)-1, (void *)-1 }, { NULL, NULL }, NULL \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*%
|
||||||
|
@@ -1330,6 +1326,7 @@ ISC_LANG_ENDDECLS
|
||||||
|
_n->buffer = NULL; \
|
||||||
|
ISC_LINK_INIT(_n, link); \
|
||||||
|
ISC_LIST_INIT(_n->list); \
|
||||||
|
+ _n->ht = NULL; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define DNS_NAME_RESET(n) \
|
||||||
|
diff --git a/lib/dns/message.c b/lib/dns/message.c
|
||||||
|
index 761a8e1..8654e92 100644
|
||||||
|
--- a/lib/dns/message.c
|
||||||
|
+++ b/lib/dns/message.c
|
||||||
|
@@ -22,6 +22,8 @@
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <isc/buffer.h>
|
||||||
|
+#include <isc/hash.h>
|
||||||
|
+#include <isc/ht.h>
|
||||||
|
#include <isc/mem.h>
|
||||||
|
#include <isc/print.h>
|
||||||
|
#include <isc/result.h>
|
||||||
|
@@ -493,9 +495,11 @@ msgresetsigs(dns_message_t *msg, bool replying) {
|
||||||
|
} else {
|
||||||
|
dns_rdataset_disassociate(msg->tsig);
|
||||||
|
isc_mempool_put(msg->rdspool, msg->tsig);
|
||||||
|
+ msg->tsig = NULL;
|
||||||
|
if (msg->querytsig != NULL) {
|
||||||
|
dns_rdataset_disassociate(msg->querytsig);
|
||||||
|
isc_mempool_put(msg->rdspool, msg->querytsig);
|
||||||
|
+ msg->querytsig = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dns_message_puttempname(msg, &msg->tsigname);
|
||||||
|
@@ -790,6 +794,18 @@ dns_message_detach(dns_message_t **messagep) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static isc_result_t
|
||||||
|
+name_hash_add(isc_ht_t *ht, dns_name_t *name, dns_name_t **foundp) {
|
||||||
|
+ isc_result_t result = isc_ht_find(ht, name->ndata, name->length,
|
||||||
|
+ (void **)foundp);
|
||||||
|
+ if (result == ISC_R_SUCCESS) {
|
||||||
|
+ return (ISC_R_EXISTS);
|
||||||
|
+ }
|
||||||
|
+ result = isc_ht_add(ht, name->ndata, name->length, (void *)name);
|
||||||
|
+ INSIST(result == ISC_R_SUCCESS);
|
||||||
|
+ return (ISC_R_SUCCESS);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static isc_result_t
|
||||||
|
findname(dns_name_t **foundname, const dns_name_t *target,
|
||||||
|
dns_namelist_t *section) {
|
||||||
|
@@ -809,29 +825,26 @@ findname(dns_name_t **foundname, const dns_name_t *target,
|
||||||
|
return (ISC_R_NOTFOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
-isc_result_t
|
||||||
|
-dns_message_find(const dns_name_t *name, dns_rdataclass_t rdclass,
|
||||||
|
- dns_rdatatype_t type, dns_rdatatype_t covers,
|
||||||
|
- dns_rdataset_t **rdataset) {
|
||||||
|
- dns_rdataset_t *curr;
|
||||||
|
-
|
||||||
|
- REQUIRE(name != NULL);
|
||||||
|
- REQUIRE(rdataset == NULL || *rdataset == NULL);
|
||||||
|
-
|
||||||
|
- for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
|
||||||
|
- curr = ISC_LIST_PREV(curr, link))
|
||||||
|
- {
|
||||||
|
- if (curr->rdclass == rdclass && curr->type == type &&
|
||||||
|
- curr->covers == covers)
|
||||||
|
- {
|
||||||
|
- if (rdataset != NULL) {
|
||||||
|
- *rdataset = curr;
|
||||||
|
- }
|
||||||
|
- return (ISC_R_SUCCESS);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+typedef struct __attribute__((__packed__)) rds_key {
|
||||||
|
+ dns_rdataclass_t rdclass;
|
||||||
|
+ dns_rdatatype_t type;
|
||||||
|
+ dns_rdatatype_t covers;
|
||||||
|
+} rds_key_t;
|
||||||
|
|
||||||
|
- return (ISC_R_NOTFOUND);
|
||||||
|
+static isc_result_t
|
||||||
|
+rds_hash_add(isc_ht_t *ht, dns_rdataset_t *rds, dns_rdataset_t **foundp) {
|
||||||
|
+ rds_key_t key = { .rdclass = rds->rdclass,
|
||||||
|
+ .type = rds->type,
|
||||||
|
+ .covers = rds->covers };
|
||||||
|
+ isc_result_t result = isc_ht_find(ht, (const unsigned char *)&key,
|
||||||
|
+ sizeof(key), (void **)foundp);
|
||||||
|
+ if (result == ISC_R_SUCCESS) {
|
||||||
|
+ return (ISC_R_EXISTS);
|
||||||
|
+ }
|
||||||
|
+ result = isc_ht_add(ht, (const unsigned char *)&key, sizeof(key),
|
||||||
|
+ (void *)rds);
|
||||||
|
+ INSIST(result == ISC_R_SUCCESS);
|
||||||
|
+ return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
@@ -958,6 +971,18 @@ getrdata(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+cleanup_name_hashmaps(dns_namelist_t *section) {
|
||||||
|
+ dns_name_t *name = NULL;
|
||||||
|
+ for (name = ISC_LIST_HEAD(*section); name != NULL;
|
||||||
|
+ name = ISC_LIST_NEXT(name, link))
|
||||||
|
+ {
|
||||||
|
+ if (name->ht != NULL) {
|
||||||
|
+ isc_ht_destroy(&name->ht);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static isc_result_t
|
||||||
|
getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
unsigned int options) {
|
||||||
|
@@ -967,13 +992,19 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
dns_name_t *name2 = NULL;
|
||||||
|
dns_rdataset_t *rdataset = NULL;
|
||||||
|
dns_rdatalist_t *rdatalist = NULL;
|
||||||
|
- isc_result_t result;
|
||||||
|
+ isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
dns_rdatatype_t rdtype;
|
||||||
|
dns_rdataclass_t rdclass;
|
||||||
|
dns_namelist_t *section = &msg->sections[DNS_SECTION_QUESTION];
|
||||||
|
bool best_effort = ((options & DNS_MESSAGEPARSE_BESTEFFORT) != 0);
|
||||||
|
bool seen_problem = false;
|
||||||
|
bool free_name = false;
|
||||||
|
+ bool free_ht = false;
|
||||||
|
+ isc_ht_t *name_map = NULL;
|
||||||
|
+
|
||||||
|
+ if (msg->counts[DNS_SECTION_QUESTION] > 1) {
|
||||||
|
+ isc_ht_init(&name_map, msg->mctx, 1, ISC_HT_CASE_INSENSITIVE);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
for (count = 0; count < msg->counts[DNS_SECTION_QUESTION]; count++) {
|
||||||
|
name = NULL;
|
||||||
|
@@ -994,13 +1025,19 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* If there is only one QNAME, skip the duplicity checks */
|
||||||
|
+ if (name_map == NULL) {
|
||||||
|
+ result = ISC_R_SUCCESS;
|
||||||
|
+ goto skip_name_check;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Run through the section, looking to see if this name
|
||||||
|
* is already there. If it is found, put back the allocated
|
||||||
|
* name since we no longer need it, and set our name pointer
|
||||||
|
* to point to the name we found.
|
||||||
|
*/
|
||||||
|
- result = findname(&name2, name, section);
|
||||||
|
+ result = name_hash_add(name_map, name, &name2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If it is the first name in the section, accept it.
|
||||||
|
@@ -1012,19 +1049,25 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
* this should be legal or not. In either case we no longer
|
||||||
|
* need this name pointer.
|
||||||
|
*/
|
||||||
|
- if (result != ISC_R_SUCCESS) {
|
||||||
|
+ skip_name_check:
|
||||||
|
+ switch (result) {
|
||||||
|
+ case ISC_R_SUCCESS:
|
||||||
|
if (!ISC_LIST_EMPTY(*section)) {
|
||||||
|
DO_ERROR(DNS_R_FORMERR);
|
||||||
|
}
|
||||||
|
ISC_LIST_APPEND(*section, name, link);
|
||||||
|
- free_name = false;
|
||||||
|
- } else {
|
||||||
|
+ break;
|
||||||
|
+ case ISC_R_EXISTS:
|
||||||
|
dns_message_puttempname(msg, &name);
|
||||||
|
name = name2;
|
||||||
|
name2 = NULL;
|
||||||
|
- free_name = false;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ free_name = false;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Get type and class.
|
||||||
|
*/
|
||||||
|
@@ -1054,14 +1097,6 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
msg->tkey = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /*
|
||||||
|
- * Can't ask the same question twice.
|
||||||
|
- */
|
||||||
|
- result = dns_message_find(name, rdclass, rdtype, 0, NULL);
|
||||||
|
- if (result == ISC_R_SUCCESS) {
|
||||||
|
- DO_ERROR(DNS_R_FORMERR);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* Allocate a new rdatalist.
|
||||||
|
*/
|
||||||
|
@@ -1071,6 +1106,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
rdataset = isc_mempool_get(msg->rdspool);
|
||||||
|
+ dns_rdataset_init(rdataset);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert rdatalist to rdataset, and attach the latter to
|
||||||
|
@@ -1078,8 +1114,6 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
*/
|
||||||
|
rdatalist->type = rdtype;
|
||||||
|
rdatalist->rdclass = rdclass;
|
||||||
|
-
|
||||||
|
- dns_rdataset_init(rdataset);
|
||||||
|
result = dns_rdatalist_tordataset(rdatalist, rdataset);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
goto cleanup;
|
||||||
|
@@ -1087,24 +1121,66 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
|
||||||
|
rdataset->attributes |= DNS_RDATASETATTR_QUESTION;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * Skip the duplicity check for first rdataset
|
||||||
|
+ */
|
||||||
|
+ if (ISC_LIST_EMPTY(name->list)) {
|
||||||
|
+ result = ISC_R_SUCCESS;
|
||||||
|
+ goto skip_rds_check;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Can't ask the same question twice.
|
||||||
|
+ */
|
||||||
|
+ if (name->ht == NULL) {
|
||||||
|
+ isc_ht_init(&name->ht, msg->mctx, 1,
|
||||||
|
+ ISC_HT_CASE_SENSITIVE);
|
||||||
|
+ free_ht = true;
|
||||||
|
+
|
||||||
|
+ INSIST(ISC_LIST_HEAD(name->list) ==
|
||||||
|
+ ISC_LIST_TAIL(name->list));
|
||||||
|
+
|
||||||
|
+ dns_rdataset_t *old_rdataset =
|
||||||
|
+ ISC_LIST_HEAD(name->list);
|
||||||
|
+
|
||||||
|
+ result = rds_hash_add(name->ht, old_rdataset, NULL);
|
||||||
|
+
|
||||||
|
+ INSIST(result == ISC_R_SUCCESS);
|
||||||
|
+ }
|
||||||
|
+ result = rds_hash_add(name->ht, rdataset, NULL);
|
||||||
|
+ if (result == ISC_R_EXISTS) {
|
||||||
|
+ DO_ERROR(DNS_R_FORMERR);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ skip_rds_check:
|
||||||
|
ISC_LIST_APPEND(name->list, rdataset, link);
|
||||||
|
+
|
||||||
|
rdataset = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seen_problem) {
|
||||||
|
- return (DNS_R_RECOVERABLE);
|
||||||
|
+ result = DNS_R_RECOVERABLE;
|
||||||
|
}
|
||||||
|
- return (ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (rdataset != NULL) {
|
||||||
|
- INSIST(!dns_rdataset_isassociated(rdataset));
|
||||||
|
+ if (dns_rdataset_isassociated(rdataset)) {
|
||||||
|
+ dns_rdataset_disassociate(rdataset);
|
||||||
|
+ }
|
||||||
|
isc_mempool_put(msg->rdspool, rdataset);
|
||||||
|
}
|
||||||
|
if (free_name) {
|
||||||
|
dns_message_puttempname(msg, &name);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (free_ht) {
|
||||||
|
+ cleanup_name_hashmaps(section);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (name_map != NULL) {
|
||||||
|
+ isc_ht_destroy(&name_map);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1184,17 +1260,24 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
dns_name_t *name = NULL;
|
||||||
|
dns_name_t *name2 = NULL;
|
||||||
|
dns_rdataset_t *rdataset = NULL;
|
||||||
|
+ dns_rdataset_t *found_rdataset = NULL;
|
||||||
|
dns_rdatalist_t *rdatalist = NULL;
|
||||||
|
- isc_result_t result;
|
||||||
|
+ isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
dns_rdatatype_t rdtype, covers;
|
||||||
|
dns_rdataclass_t rdclass;
|
||||||
|
dns_rdata_t *rdata = NULL;
|
||||||
|
dns_ttl_t ttl;
|
||||||
|
dns_namelist_t *section = &msg->sections[sectionid];
|
||||||
|
- bool free_name = false, free_rdataset = false, seen_problem = false;
|
||||||
|
+ bool free_name = false, seen_problem = false;
|
||||||
|
+ bool free_ht = false;
|
||||||
|
bool preserve_order = ((options & DNS_MESSAGEPARSE_PRESERVEORDER) != 0);
|
||||||
|
bool best_effort = ((options & DNS_MESSAGEPARSE_BESTEFFORT) != 0);
|
||||||
|
bool isedns, issigzero, istsig;
|
||||||
|
+ isc_ht_t *name_map = NULL;
|
||||||
|
+
|
||||||
|
+ if (msg->counts[sectionid] > 1) {
|
||||||
|
+ isc_ht_init(&name_map, msg->mctx, 1, ISC_HT_CASE_INSENSITIVE);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
for (count = 0; count < msg->counts[sectionid]; count++) {
|
||||||
|
int recstart = source->current;
|
||||||
|
@@ -1202,10 +1285,10 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
|
||||||
|
skip_name_search = false;
|
||||||
|
skip_type_search = false;
|
||||||
|
- free_rdataset = false;
|
||||||
|
isedns = false;
|
||||||
|
issigzero = false;
|
||||||
|
istsig = false;
|
||||||
|
+ found_rdataset = NULL;
|
||||||
|
|
||||||
|
name = NULL;
|
||||||
|
result = dns_message_gettempname(msg, &name);
|
||||||
|
@@ -1245,8 +1328,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
if (msg->rdclass_set == 0 &&
|
||||||
|
rdtype != dns_rdatatype_opt && /* class is UDP SIZE */
|
||||||
|
rdtype != dns_rdatatype_tsig && /* class is ANY */
|
||||||
|
- rdtype != dns_rdatatype_tkey)
|
||||||
|
- { /* class is undefined */
|
||||||
|
+ rdtype != dns_rdatatype_tkey) /* class is undefined */
|
||||||
|
+ {
|
||||||
|
msg->rdclass = rdclass;
|
||||||
|
msg->rdclass_set = 1;
|
||||||
|
}
|
||||||
|
@@ -1353,10 +1436,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
* Then put the meta-class back into the finished rdata.
|
||||||
|
*/
|
||||||
|
rdata = newrdata(msg);
|
||||||
|
- if (rdata == NULL) {
|
||||||
|
- result = ISC_R_NOMEMORY;
|
||||||
|
- goto cleanup;
|
||||||
|
- }
|
||||||
|
if (msg->opcode == dns_opcode_update &&
|
||||||
|
update(sectionid, rdclass))
|
||||||
|
{
|
||||||
|
@@ -1445,34 +1524,62 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
free_name = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
+ if (name_map == NULL) {
|
||||||
|
+ result = ISC_R_SUCCESS;
|
||||||
|
+ goto skip_name_check;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Run through the section, looking to see if this name
|
||||||
|
* is already there. If it is found, put back the
|
||||||
|
* allocated name since we no longer need it, and set
|
||||||
|
* our name pointer to point to the name we found.
|
||||||
|
*/
|
||||||
|
- result = findname(&name2, name, section);
|
||||||
|
+ result = name_hash_add(name_map, name, &name2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If it is a new name, append to the section.
|
||||||
|
*/
|
||||||
|
- if (result == ISC_R_SUCCESS) {
|
||||||
|
+ skip_name_check:
|
||||||
|
+ switch (result) {
|
||||||
|
+ case ISC_R_SUCCESS:
|
||||||
|
+ ISC_LIST_APPEND(*section, name, link);
|
||||||
|
+ break;
|
||||||
|
+ case ISC_R_EXISTS:
|
||||||
|
dns_message_puttempname(msg, &name);
|
||||||
|
name = name2;
|
||||||
|
- } else {
|
||||||
|
- ISC_LIST_APPEND(*section, name, link);
|
||||||
|
+ name2 = NULL;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ UNREACHABLE();
|
||||||
|
}
|
||||||
|
free_name = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ rdatalist = newrdatalist(msg);
|
||||||
|
+ rdatalist->type = rdtype;
|
||||||
|
+ rdatalist->covers = covers;
|
||||||
|
+ rdatalist->rdclass = rdclass;
|
||||||
|
+ rdatalist->ttl = ttl;
|
||||||
|
+
|
||||||
|
+ dns_message_gettemprdataset(msg, &rdataset);
|
||||||
|
+ RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) ==
|
||||||
|
+ ISC_R_SUCCESS);
|
||||||
|
+ dns_rdataset_setownercase(rdataset, name);
|
||||||
|
+ rdatalist = NULL;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Search name for the particular type and class.
|
||||||
|
* Skip this stage if in update mode or this is a meta-type.
|
||||||
|
*/
|
||||||
|
- if (preserve_order || msg->opcode == dns_opcode_update ||
|
||||||
|
- skip_type_search)
|
||||||
|
+ if (isedns || istsig || issigzero) {
|
||||||
|
+ /* Skip adding the rdataset to the tables */
|
||||||
|
+ } else if (preserve_order || msg->opcode == dns_opcode_update ||
|
||||||
|
+ skip_type_search)
|
||||||
|
{
|
||||||
|
- result = ISC_R_NOTFOUND;
|
||||||
|
+ result = ISC_R_SUCCESS;
|
||||||
|
+
|
||||||
|
+ ISC_LIST_APPEND(name->list, rdataset, link);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* If this is a type that can only occur in
|
||||||
|
@@ -1482,59 +1589,71 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
DO_ERROR(DNS_R_FORMERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
- rdataset = NULL;
|
||||||
|
- result = dns_message_find(name, rdclass, rdtype, covers,
|
||||||
|
- &rdataset);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * If we found an rdataset that matches, we need to
|
||||||
|
- * 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. When appending, make certain that the type isn't
|
||||||
|
- * a singleton type, such as SOA or CNAME.
|
||||||
|
- *
|
||||||
|
- * 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)) {
|
||||||
|
- dns_rdata_t *first;
|
||||||
|
- dns_rdatalist_fromrdataset(rdataset,
|
||||||
|
- &rdatalist);
|
||||||
|
- first = ISC_LIST_HEAD(rdatalist->rdata);
|
||||||
|
- INSIST(first != NULL);
|
||||||
|
- if (dns_rdata_compare(rdata, first) != 0) {
|
||||||
|
- DO_ERROR(DNS_R_FORMERR);
|
||||||
|
- }
|
||||||
|
+ if (ISC_LIST_EMPTY(name->list)) {
|
||||||
|
+ result = ISC_R_SUCCESS;
|
||||||
|
+ goto skip_rds_check;
|
||||||
|
}
|
||||||
|
- }
|
||||||
|
|
||||||
|
- if (result == ISC_R_NOTFOUND) {
|
||||||
|
- rdataset = isc_mempool_get(msg->rdspool);
|
||||||
|
- free_rdataset = true;
|
||||||
|
+ if (name->ht == NULL) {
|
||||||
|
+ isc_ht_init(&name->ht, msg->mctx, 1,
|
||||||
|
+ ISC_HT_CASE_SENSITIVE);
|
||||||
|
+ free_ht = true;
|
||||||
|
|
||||||
|
- rdatalist = newrdatalist(msg);
|
||||||
|
- if (rdatalist == NULL) {
|
||||||
|
- result = ISC_R_NOMEMORY;
|
||||||
|
- goto cleanup;
|
||||||
|
+ INSIST(ISC_LIST_HEAD(name->list) ==
|
||||||
|
+ ISC_LIST_TAIL(name->list));
|
||||||
|
+
|
||||||
|
+ dns_rdataset_t *old_rdataset =
|
||||||
|
+ ISC_LIST_HEAD(name->list);
|
||||||
|
+
|
||||||
|
+ result = rds_hash_add(name->ht, old_rdataset,
|
||||||
|
+ NULL);
|
||||||
|
+
|
||||||
|
+ INSIST(result == ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
+ found_rdataset = NULL;
|
||||||
|
+ result = rds_hash_add(name->ht, rdataset,
|
||||||
|
+ &found_rdataset);
|
||||||
|
|
||||||
|
- rdatalist->type = rdtype;
|
||||||
|
- rdatalist->covers = covers;
|
||||||
|
- rdatalist->rdclass = rdclass;
|
||||||
|
- rdatalist->ttl = ttl;
|
||||||
|
+ /*
|
||||||
|
+ * If we found an rdataset that matches, we need to
|
||||||
|
+ * 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. When appending, make
|
||||||
|
+ * certain that the type isn't a singleton type, such as
|
||||||
|
+ * SOA or CNAME.
|
||||||
|
+ *
|
||||||
|
+ * Note that this check will be bypassed when preserving
|
||||||
|
+ * order, the opcode is an update, or the type search is
|
||||||
|
+ * skipped.
|
||||||
|
+ */
|
||||||
|
+ skip_rds_check:
|
||||||
|
+ switch (result) {
|
||||||
|
+ case ISC_R_EXISTS:
|
||||||
|
+ /* Free the rdataset we used as the key */
|
||||||
|
+ dns_rdataset_disassociate(rdataset);
|
||||||
|
+ isc_mempool_put(msg->rdspool, rdataset);
|
||||||
|
+ result = ISC_R_SUCCESS;
|
||||||
|
+ rdataset = found_rdataset;
|
||||||
|
|
||||||
|
- dns_rdataset_init(rdataset);
|
||||||
|
- RUNTIME_CHECK(
|
||||||
|
- dns_rdatalist_tordataset(rdatalist, rdataset) ==
|
||||||
|
- ISC_R_SUCCESS);
|
||||||
|
- dns_rdataset_setownercase(rdataset, name);
|
||||||
|
+ if (!dns_rdatatype_issingleton(rdtype)) {
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (!isedns && !istsig && !issigzero) {
|
||||||
|
+ dns_rdatalist_fromrdataset(rdataset,
|
||||||
|
+ &rdatalist);
|
||||||
|
+ dns_rdata_t *first =
|
||||||
|
+ ISC_LIST_HEAD(rdatalist->rdata);
|
||||||
|
+ INSIST(first != NULL);
|
||||||
|
+ if (dns_rdata_compare(rdata, first) != 0) {
|
||||||
|
+ DO_ERROR(DNS_R_FORMERR);
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case ISC_R_SUCCESS:
|
||||||
|
ISC_LIST_APPEND(name->list, rdataset, link);
|
||||||
|
- free_rdataset = false;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ UNREACHABLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1569,8 +1688,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
dns_rcode_t ercode;
|
||||||
|
|
||||||
|
msg->opt = rdataset;
|
||||||
|
- rdataset = NULL;
|
||||||
|
- free_rdataset = false;
|
||||||
|
ercode = (dns_rcode_t)((msg->opt->ttl &
|
||||||
|
DNS_MESSAGE_EDNSRCODE_MASK) >>
|
||||||
|
20);
|
||||||
|
@@ -1581,8 +1698,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
msg->sig0 = rdataset;
|
||||||
|
msg->sig0name = name;
|
||||||
|
msg->sigstart = recstart;
|
||||||
|
- rdataset = NULL;
|
||||||
|
- free_rdataset = false;
|
||||||
|
free_name = false;
|
||||||
|
} else if (istsig) {
|
||||||
|
msg->tsig = rdataset;
|
||||||
|
@@ -1592,22 +1707,17 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
* Windows doesn't like TSIG names to be compressed.
|
||||||
|
*/
|
||||||
|
msg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS;
|
||||||
|
- rdataset = NULL;
|
||||||
|
- free_rdataset = false;
|
||||||
|
free_name = false;
|
||||||
|
}
|
||||||
|
+ rdataset = NULL;
|
||||||
|
|
||||||
|
if (seen_problem) {
|
||||||
|
if (free_name) {
|
||||||
|
dns_message_puttempname(msg, &name);
|
||||||
|
}
|
||||||
|
- if (free_rdataset) {
|
||||||
|
- isc_mempool_put(msg->rdspool, rdataset);
|
||||||
|
- }
|
||||||
|
- free_name = free_rdataset = false;
|
||||||
|
+ free_name = false;
|
||||||
|
}
|
||||||
|
INSIST(!free_name);
|
||||||
|
- INSIST(!free_rdataset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -1625,16 +1735,24 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seen_problem) {
|
||||||
|
- return (DNS_R_RECOVERABLE);
|
||||||
|
+ result = DNS_R_RECOVERABLE;
|
||||||
|
}
|
||||||
|
- return (ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
+ if (rdataset != NULL && rdataset != found_rdataset) {
|
||||||
|
+ dns_rdataset_disassociate(rdataset);
|
||||||
|
+ isc_mempool_put(msg->rdspool, rdataset);
|
||||||
|
+ }
|
||||||
|
if (free_name) {
|
||||||
|
dns_message_puttempname(msg, &name);
|
||||||
|
}
|
||||||
|
- if (free_rdataset) {
|
||||||
|
- isc_mempool_put(msg->rdspool, rdataset);
|
||||||
|
+
|
||||||
|
+ if (free_ht) {
|
||||||
|
+ cleanup_name_hashmaps(section);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (name_map != NULL) {
|
||||||
|
+ isc_ht_destroy(&name_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
@@ -2452,7 +2570,7 @@ dns_message_findname(dns_message_t *msg, dns_section_t section,
|
||||||
|
const dns_name_t *target, dns_rdatatype_t type,
|
||||||
|
dns_rdatatype_t covers, dns_name_t **name,
|
||||||
|
dns_rdataset_t **rdataset) {
|
||||||
|
- dns_name_t *foundname;
|
||||||
|
+ dns_name_t *foundname = NULL;
|
||||||
|
isc_result_t result;
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -2499,22 +2617,6 @@ dns_message_findname(dns_message_t *msg, dns_section_t section,
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
-void
|
||||||
|
-dns_message_movename(dns_message_t *msg, dns_name_t *name,
|
||||||
|
- dns_section_t fromsection, dns_section_t tosection) {
|
||||||
|
- REQUIRE(msg != NULL);
|
||||||
|
- REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
|
||||||
|
- REQUIRE(name != NULL);
|
||||||
|
- REQUIRE(VALID_NAMED_SECTION(fromsection));
|
||||||
|
- REQUIRE(VALID_NAMED_SECTION(tosection));
|
||||||
|
-
|
||||||
|
- /*
|
||||||
|
- * Unlink the name from the old section
|
||||||
|
- */
|
||||||
|
- ISC_LIST_UNLINK(msg->sections[fromsection], name, link);
|
||||||
|
- ISC_LIST_APPEND(msg->sections[tosection], name, link);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
void
|
||||||
|
dns_message_addname(dns_message_t *msg, dns_name_t *name,
|
||||||
|
dns_section_t section) {
|
||||||
|
@@ -2591,6 +2693,10 @@ dns_message_puttempname(dns_message_t *msg, dns_name_t **itemp) {
|
||||||
|
REQUIRE(!ISC_LINK_LINKED(item, link));
|
||||||
|
REQUIRE(ISC_LIST_HEAD(item->list) == NULL);
|
||||||
|
|
||||||
|
+ if (item->ht != NULL) {
|
||||||
|
+ isc_ht_destroy(&item->ht);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* we need to check this in case dns_name_dup() was used.
|
||||||
|
*/
|
||||||
|
diff --git a/lib/dns/name.c b/lib/dns/name.c
|
||||||
|
index 8a258a2..90044ba 100644
|
||||||
|
--- a/lib/dns/name.c
|
||||||
|
+++ b/lib/dns/name.c
|
||||||
|
@@ -188,6 +188,7 @@ dns_name_invalidate(dns_name_t *name) {
|
||||||
|
name->offsets = NULL;
|
||||||
|
name->buffer = NULL;
|
||||||
|
ISC_LINK_INIT(name, link);
|
||||||
|
+ INSIST(name->ht == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
diff --git a/lib/isc/ht.c b/lib/isc/ht.c
|
||||||
|
index eaf2b3c..e11050f 100644
|
||||||
|
--- a/lib/isc/ht.c
|
||||||
|
+++ b/lib/isc/ht.c
|
||||||
|
@@ -93,11 +93,54 @@ maybe_rehash(isc_ht_t *ht, size_t newcount);
|
||||||
|
static isc_result_t
|
||||||
|
isc__ht_iter_next(isc_ht_iter_t *it);
|
||||||
|
|
||||||
|
+static uint8_t maptolower[] = {
|
||||||
|
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||||
|
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||||
|
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
|
||||||
|
+ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||||
|
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
|
||||||
|
+ 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
||||||
|
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
|
||||||
|
+ 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||||
|
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
|
||||||
|
+ 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
|
||||||
|
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
|
||||||
|
+ 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||||
|
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
|
||||||
|
+ 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
|
||||||
|
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
|
||||||
|
+ 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||||
|
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
|
||||||
|
+ 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
|
||||||
|
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
|
||||||
|
+ 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
|
||||||
|
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
|
||||||
|
+ 0xfc, 0xfd, 0xfe, 0xff
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+memcasecmp(const void *vs1, const void *vs2, size_t len) {
|
||||||
|
+ uint8_t const *s1 = vs1;
|
||||||
|
+ uint8_t const *s2 = vs2;
|
||||||
|
+ for (size_t i = 0; i < len; i++) {
|
||||||
|
+ uint8_t u1 = s1[i];
|
||||||
|
+ uint8_t u2 = s2[i];
|
||||||
|
+ int U1 = maptolower[u1];
|
||||||
|
+ int U2 = maptolower[u2];
|
||||||
|
+ int diff = U1 - U2;
|
||||||
|
+ if (diff) {
|
||||||
|
+ return diff;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static bool
|
||||||
|
isc__ht_node_match(isc_ht_node_t *node, const uint32_t hashval,
|
||||||
|
- const uint8_t *key, uint32_t keysize) {
|
||||||
|
+ const uint8_t *key, uint32_t keysize, bool case_sensitive) {
|
||||||
|
return (node->hashval == hashval && node->keysize == keysize &&
|
||||||
|
- memcmp(node->key, key, keysize) == 0);
|
||||||
|
+ (case_sensitive ? (memcmp(node->key, key, keysize) == 0)
|
||||||
|
+ : (memcasecmp(node->key, key, keysize) == 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
@@ -341,7 +384,9 @@ nexttable:
|
||||||
|
for (isc_ht_node_t *node = ht->table[findex][hash]; node != NULL;
|
||||||
|
node = node->next)
|
||||||
|
{
|
||||||
|
- if (isc__ht_node_match(node, hashval, key, keysize)) {
|
||||||
|
+ if (isc__ht_node_match(node, hashval, key, keysize,
|
||||||
|
+ ht->case_sensitive))
|
||||||
|
+ {
|
||||||
|
return (node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -390,7 +435,9 @@ isc__ht_delete(isc_ht_t *ht, const unsigned char *key, const uint32_t keysize,
|
||||||
|
for (isc_ht_node_t *node = ht->table[idx][hash]; node != NULL;
|
||||||
|
prev = node, node = node->next)
|
||||||
|
{
|
||||||
|
- if (isc__ht_node_match(node, hashval, key, keysize)) {
|
||||||
|
+ if (isc__ht_node_match(node, hashval, key, keysize,
|
||||||
|
+ ht->case_sensitive))
|
||||||
|
+ {
|
||||||
|
if (prev == NULL) {
|
||||||
|
ht->table[idx][hash] = node->next;
|
||||||
|
} else {
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
600
backport-CVE-2023-50387-CVE-2023-50868.patch
Normal file
600
backport-CVE-2023-50387-CVE-2023-50868.patch
Normal file
@ -0,0 +1,600 @@
|
|||||||
|
From c12608ca934c0433d280e65fe6c631013e200cfe Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
|
||||||
|
Date: Thu, 11 Jan 2024 12:03:24 +0100
|
||||||
|
Subject: [PATCH] Split fast and slow task queues
|
||||||
|
|
||||||
|
Change the taskmgr (and thus netmgr) in a way that it supports fast and
|
||||||
|
slow task queues. The fast queue is used for incoming DNS traffic and
|
||||||
|
it will pass the processing to the slow queue for sending outgoing DNS
|
||||||
|
messages and processing resolver messages.
|
||||||
|
|
||||||
|
In the future, more tasks might get moved to the slow queues, so the
|
||||||
|
cached and authoritative DNS traffic can be handled without being slowed
|
||||||
|
down by operations that take longer time to process.
|
||||||
|
|
||||||
|
Conflict:NA
|
||||||
|
Reference:https://downloads.isc.org/isc/bind/9.18.24/patches/0004-CVE-2023-50387-CVE-2023-50868.patch
|
||||||
|
|
||||||
|
(cherry picked from commit 1b3b0cef224e7a9e8279c5cfe2f7e188e3777cc7)
|
||||||
|
---
|
||||||
|
lib/dns/dst_api.c | 27 +++++++++----
|
||||||
|
lib/dns/include/dns/validator.h | 1 +
|
||||||
|
lib/dns/include/dst/dst.h | 4 ++
|
||||||
|
lib/dns/resolver.c | 4 +-
|
||||||
|
lib/dns/validator.c | 67 +++++++++++++++------------------
|
||||||
|
lib/isc/include/isc/netmgr.h | 3 ++
|
||||||
|
lib/isc/netmgr/http.c | 18 ++++-----
|
||||||
|
lib/isc/netmgr/netmgr-int.h | 1 +
|
||||||
|
lib/isc/netmgr/netmgr.c | 38 ++++++++++++-------
|
||||||
|
lib/isc/netmgr/tcp.c | 6 +--
|
||||||
|
lib/isc/netmgr/tcpdns.c | 4 +-
|
||||||
|
lib/isc/netmgr/tlsdns.c | 4 +-
|
||||||
|
lib/isc/netmgr/tlsstream.c | 12 +++---
|
||||||
|
lib/isc/netmgr/udp.c | 6 +--
|
||||||
|
14 files changed, 109 insertions(+), 86 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c
|
||||||
|
index 4ffda8b..0658c69 100644
|
||||||
|
--- a/lib/dns/dst_api.c
|
||||||
|
+++ b/lib/dns/dst_api.c
|
||||||
|
@@ -164,7 +164,8 @@ computeid(dst_key_t *key);
|
||||||
|
static isc_result_t
|
||||||
|
frombuffer(const dns_name_t *name, unsigned int alg, unsigned int flags,
|
||||||
|
unsigned int protocol, dns_rdataclass_t rdclass,
|
||||||
|
- isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp);
|
||||||
|
+ isc_buffer_t *source, isc_mem_t *mctx, bool no_rdata,
|
||||||
|
+ dst_key_t **keyp);
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
algorithm_status(unsigned int alg);
|
||||||
|
@@ -753,6 +754,13 @@ dst_key_todns(const dst_key_t *key, isc_buffer_t *target) {
|
||||||
|
isc_result_t
|
||||||
|
dst_key_fromdns(const dns_name_t *name, dns_rdataclass_t rdclass,
|
||||||
|
isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp) {
|
||||||
|
+ return (dst_key_fromdns_ex(name, rdclass, source, mctx, false, keyp));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+isc_result_t
|
||||||
|
+dst_key_fromdns_ex(const dns_name_t *name, dns_rdataclass_t rdclass,
|
||||||
|
+ isc_buffer_t *source, isc_mem_t *mctx, bool no_rdata,
|
||||||
|
+ dst_key_t **keyp) {
|
||||||
|
uint8_t alg, proto;
|
||||||
|
uint32_t flags, extflags;
|
||||||
|
dst_key_t *key = NULL;
|
||||||
|
@@ -783,7 +791,7 @@ dst_key_fromdns(const dns_name_t *name, dns_rdataclass_t rdclass,
|
||||||
|
}
|
||||||
|
|
||||||
|
result = frombuffer(name, alg, flags, proto, rdclass, source, mctx,
|
||||||
|
- &key);
|
||||||
|
+ no_rdata, &key);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
@@ -804,7 +812,7 @@ dst_key_frombuffer(const dns_name_t *name, unsigned int alg, unsigned int flags,
|
||||||
|
REQUIRE(dst_initialized);
|
||||||
|
|
||||||
|
result = frombuffer(name, alg, flags, protocol, rdclass, source, mctx,
|
||||||
|
- &key);
|
||||||
|
+ false, &key);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
@@ -2351,7 +2359,8 @@ computeid(dst_key_t *key) {
|
||||||
|
static isc_result_t
|
||||||
|
frombuffer(const dns_name_t *name, unsigned int alg, unsigned int flags,
|
||||||
|
unsigned int protocol, dns_rdataclass_t rdclass,
|
||||||
|
- isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp) {
|
||||||
|
+ isc_buffer_t *source, isc_mem_t *mctx, bool no_rdata,
|
||||||
|
+ dst_key_t **keyp) {
|
||||||
|
dst_key_t *key;
|
||||||
|
isc_result_t ret;
|
||||||
|
|
||||||
|
@@ -2376,10 +2385,12 @@ frombuffer(const dns_name_t *name, unsigned int alg, unsigned int flags,
|
||||||
|
return (DST_R_UNSUPPORTEDALG);
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = key->func->fromdns(key, source);
|
||||||
|
- if (ret != ISC_R_SUCCESS) {
|
||||||
|
- dst_key_free(&key);
|
||||||
|
- return (ret);
|
||||||
|
+ if (!no_rdata) {
|
||||||
|
+ ret = key->func->fromdns(key, source);
|
||||||
|
+ if (ret != ISC_R_SUCCESS) {
|
||||||
|
+ dst_key_free(&key);
|
||||||
|
+ return (ret);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/lib/dns/include/dns/validator.h b/lib/dns/include/dns/validator.h
|
||||||
|
index 383dcb4..352a60a 100644
|
||||||
|
--- a/lib/dns/include/dns/validator.h
|
||||||
|
+++ b/lib/dns/include/dns/validator.h
|
||||||
|
@@ -148,6 +148,7 @@ struct dns_validator {
|
||||||
|
unsigned int depth;
|
||||||
|
unsigned int authcount;
|
||||||
|
unsigned int authfail;
|
||||||
|
+ bool failed;
|
||||||
|
isc_stdtime_t start;
|
||||||
|
};
|
||||||
|
|
||||||
|
diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h
|
||||||
|
index ca292b0..f845e9b 100644
|
||||||
|
--- a/lib/dns/include/dst/dst.h
|
||||||
|
+++ b/lib/dns/include/dst/dst.h
|
||||||
|
@@ -482,6 +482,10 @@ dst_key_tofile(const dst_key_t *key, int type, const char *directory);
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
+dst_key_fromdns_ex(const dns_name_t *name, dns_rdataclass_t rdclass,
|
||||||
|
+ isc_buffer_t *source, isc_mem_t *mctx, bool no_rdata,
|
||||||
|
+ dst_key_t **keyp);
|
||||||
|
+isc_result_t
|
||||||
|
dst_key_fromdns(const dns_name_t *name, dns_rdataclass_t rdclass,
|
||||||
|
isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp);
|
||||||
|
/*%<
|
||||||
|
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
|
||||||
|
index 4b3d1c0..60cac29 100644
|
||||||
|
--- a/lib/dns/resolver.c
|
||||||
|
+++ b/lib/dns/resolver.c
|
||||||
|
@@ -10408,8 +10408,8 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
|
||||||
|
* Since we have a pool of tasks we bind them to task
|
||||||
|
* queues to spread the load evenly
|
||||||
|
*/
|
||||||
|
- result = isc_task_create_bound(taskmgr, 0,
|
||||||
|
- &res->buckets[i].task, i);
|
||||||
|
+ result = isc_task_create_bound(
|
||||||
|
+ taskmgr, 0, &res->buckets[i].task, ISC_NM_TASK_SLOW(i));
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
ntasks = i;
|
||||||
|
isc_mutex_destroy(&res->buckets[i].lock);
|
||||||
|
diff --git a/lib/dns/validator.c b/lib/dns/validator.c
|
||||||
|
index 56a0ced..47c4813 100644
|
||||||
|
--- a/lib/dns/validator.c
|
||||||
|
+++ b/lib/dns/validator.c
|
||||||
|
@@ -1104,8 +1104,8 @@ create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
|
||||||
|
* 'rdataset'. If found, build a dst_key_t for it and point val->key at
|
||||||
|
* it.
|
||||||
|
*
|
||||||
|
- * If val->key is already non-NULL, locate it in the rdataset and then
|
||||||
|
- * search past it for the *next* key that could have signed 'siginfo', then
|
||||||
|
+ * If val->key is already non-NULL, start searching from the next position in
|
||||||
|
+ * 'rdataset' to find the *next* key that could have signed 'siginfo', then
|
||||||
|
* set val->key to that.
|
||||||
|
*
|
||||||
|
* Returns ISC_R_SUCCESS if a possible matching key has been found,
|
||||||
|
@@ -1118,59 +1118,59 @@ select_signing_key(dns_validator_t *val, dns_rdataset_t *rdataset) {
|
||||||
|
isc_buffer_t b;
|
||||||
|
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||||
|
dst_key_t *oldkey = val->key;
|
||||||
|
- bool foundold;
|
||||||
|
+ bool no_rdata = false;
|
||||||
|
|
||||||
|
if (oldkey == NULL) {
|
||||||
|
- foundold = true;
|
||||||
|
+ result = dns_rdataset_first(rdataset);
|
||||||
|
} else {
|
||||||
|
- foundold = false;
|
||||||
|
+ dst_key_free(&oldkey);
|
||||||
|
val->key = NULL;
|
||||||
|
+ result = dns_rdataset_next(rdataset);
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- result = dns_rdataset_first(rdataset);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
- goto failure;
|
||||||
|
+ goto done;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
do {
|
||||||
|
dns_rdataset_current(rdataset, &rdata);
|
||||||
|
|
||||||
|
isc_buffer_init(&b, rdata.data, rdata.length);
|
||||||
|
isc_buffer_add(&b, rdata.length);
|
||||||
|
INSIST(val->key == NULL);
|
||||||
|
- result = dst_key_fromdns(&siginfo->signer, rdata.rdclass, &b,
|
||||||
|
- val->view->mctx, &val->key);
|
||||||
|
+ result = dst_key_fromdns_ex(&siginfo->signer, rdata.rdclass, &b,
|
||||||
|
+ val->view->mctx, no_rdata,
|
||||||
|
+ &val->key);
|
||||||
|
if (result == ISC_R_SUCCESS) {
|
||||||
|
if (siginfo->algorithm ==
|
||||||
|
(dns_secalg_t)dst_key_alg(val->key) &&
|
||||||
|
siginfo->keyid ==
|
||||||
|
(dns_keytag_t)dst_key_id(val->key) &&
|
||||||
|
+ (dst_key_flags(val->key) & DNS_KEYFLAG_REVOKE) ==
|
||||||
|
+ 0 &&
|
||||||
|
dst_key_iszonekey(val->key))
|
||||||
|
{
|
||||||
|
- if (foundold) {
|
||||||
|
- /*
|
||||||
|
- * This is the key we're looking for.
|
||||||
|
- */
|
||||||
|
- return (ISC_R_SUCCESS);
|
||||||
|
- } else if (dst_key_compare(oldkey, val->key)) {
|
||||||
|
- foundold = true;
|
||||||
|
- dst_key_free(&oldkey);
|
||||||
|
+ if (no_rdata) {
|
||||||
|
+ /* Retry with full key */
|
||||||
|
+ dns_rdata_reset(&rdata);
|
||||||
|
+ dst_key_free(&val->key);
|
||||||
|
+ no_rdata = false;
|
||||||
|
+ continue;
|
||||||
|
}
|
||||||
|
+ /* This is the key we're looking for. */
|
||||||
|
+ goto done;
|
||||||
|
}
|
||||||
|
dst_key_free(&val->key);
|
||||||
|
}
|
||||||
|
dns_rdata_reset(&rdata);
|
||||||
|
result = dns_rdataset_next(rdataset);
|
||||||
|
+ no_rdata = true;
|
||||||
|
} while (result == ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
+done:
|
||||||
|
if (result == ISC_R_NOMORE) {
|
||||||
|
result = ISC_R_NOTFOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
-failure:
|
||||||
|
- if (oldkey != NULL) {
|
||||||
|
- dst_key_free(&oldkey);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1589,20 +1589,9 @@ validate_answer(dns_validator_t *val, bool resume) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- do {
|
||||||
|
- isc_result_t tresult;
|
||||||
|
- vresult = verify(val, val->key, &rdata,
|
||||||
|
- val->siginfo->keyid);
|
||||||
|
- if (vresult == ISC_R_SUCCESS) {
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- tresult = select_signing_key(val, val->keyset);
|
||||||
|
- if (tresult != ISC_R_SUCCESS) {
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
- } while (1);
|
||||||
|
+ vresult = verify(val, val->key, &rdata, val->siginfo->keyid);
|
||||||
|
if (vresult != ISC_R_SUCCESS) {
|
||||||
|
+ val->failed = true;
|
||||||
|
validator_log(val, ISC_LOG_DEBUG(3),
|
||||||
|
"failed to verify rdataset");
|
||||||
|
} else {
|
||||||
|
@@ -1639,9 +1628,13 @@ validate_answer(dns_validator_t *val, bool resume) {
|
||||||
|
} else {
|
||||||
|
validator_log(val, ISC_LOG_DEBUG(3),
|
||||||
|
"verify failure: %s",
|
||||||
|
- isc_result_totext(result));
|
||||||
|
+ isc_result_totext(vresult));
|
||||||
|
resume = false;
|
||||||
|
}
|
||||||
|
+ if (val->failed) {
|
||||||
|
+ result = ISC_R_NOMORE;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
if (result != ISC_R_NOMORE) {
|
||||||
|
validator_log(val, ISC_LOG_DEBUG(3),
|
||||||
|
diff --git a/lib/isc/include/isc/netmgr.h b/lib/isc/include/isc/netmgr.h
|
||||||
|
index eff33f6..d42cfe9 100644
|
||||||
|
--- a/lib/isc/include/isc/netmgr.h
|
||||||
|
+++ b/lib/isc/include/isc/netmgr.h
|
||||||
|
@@ -750,6 +750,9 @@ isc_nm_verify_tls_peer_result_string(const isc_nmhandle_t *handle);
|
||||||
|
* \li 'handle' is a valid netmgr handle object.
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#define ISC_NM_TASK_SLOW_OFFSET -2
|
||||||
|
+#define ISC_NM_TASK_SLOW(i) (ISC_NM_TASK_SLOW_OFFSET - 1 - i)
|
||||||
|
+
|
||||||
|
void
|
||||||
|
isc_nm_task_enqueue(isc_nm_t *mgr, isc_task_t *task, int threadid);
|
||||||
|
/*%<
|
||||||
|
diff --git a/lib/isc/netmgr/http.c b/lib/isc/netmgr/http.c
|
||||||
|
index d7a33d5..2220edf 100644
|
||||||
|
--- a/lib/isc/netmgr/http.c
|
||||||
|
+++ b/lib/isc/netmgr/http.c
|
||||||
|
@@ -2969,7 +2969,7 @@ isc__nm_http_set_max_streams(isc_nmsocket_t *listener,
|
||||||
|
void
|
||||||
|
isc_nm_http_set_endpoints(isc_nmsocket_t *listener,
|
||||||
|
isc_nm_http_endpoints_t *eps) {
|
||||||
|
- size_t nworkers;
|
||||||
|
+ size_t nlisteners;
|
||||||
|
|
||||||
|
REQUIRE(VALID_NMSOCK(listener));
|
||||||
|
REQUIRE(listener->type == isc_nm_httplistener);
|
||||||
|
@@ -2977,8 +2977,8 @@ isc_nm_http_set_endpoints(isc_nmsocket_t *listener,
|
||||||
|
|
||||||
|
atomic_store(&eps->in_use, true);
|
||||||
|
|
||||||
|
- nworkers = (size_t)listener->mgr->nworkers;
|
||||||
|
- for (size_t i = 0; i < nworkers; i++) {
|
||||||
|
+ nlisteners = (size_t)listener->mgr->nlisteners;
|
||||||
|
+ for (size_t i = 0; i < nlisteners; i++) {
|
||||||
|
isc__netievent__http_eps_t *ievent =
|
||||||
|
isc__nm_get_netievent_httpendpoints(listener->mgr,
|
||||||
|
listener, eps);
|
||||||
|
@@ -3003,20 +3003,20 @@ isc__nm_async_httpendpoints(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||||
|
static void
|
||||||
|
http_init_listener_endpoints(isc_nmsocket_t *listener,
|
||||||
|
isc_nm_http_endpoints_t *epset) {
|
||||||
|
- size_t nworkers;
|
||||||
|
+ size_t nlisteners;
|
||||||
|
|
||||||
|
REQUIRE(VALID_NMSOCK(listener));
|
||||||
|
REQUIRE(VALID_NM(listener->mgr));
|
||||||
|
REQUIRE(VALID_HTTP_ENDPOINTS(epset));
|
||||||
|
|
||||||
|
- nworkers = (size_t)listener->mgr->nworkers;
|
||||||
|
- INSIST(nworkers > 0);
|
||||||
|
+ nlisteners = (size_t)listener->mgr->nlisteners;
|
||||||
|
+ INSIST(nlisteners > 0);
|
||||||
|
|
||||||
|
listener->h2.listener_endpoints =
|
||||||
|
isc_mem_get(listener->mgr->mctx,
|
||||||
|
- sizeof(isc_nm_http_endpoints_t *) * nworkers);
|
||||||
|
- listener->h2.n_listener_endpoints = nworkers;
|
||||||
|
- for (size_t i = 0; i < nworkers; i++) {
|
||||||
|
+ sizeof(isc_nm_http_endpoints_t *) * nlisteners);
|
||||||
|
+ listener->h2.n_listener_endpoints = nlisteners;
|
||||||
|
+ for (size_t i = 0; i < nlisteners; i++) {
|
||||||
|
listener->h2.listener_endpoints[i] = NULL;
|
||||||
|
isc_nm_http_endpoints_attach(
|
||||||
|
epset, &listener->h2.listener_endpoints[i]);
|
||||||
|
diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h
|
||||||
|
index 364a933..6aca9ab 100644
|
||||||
|
--- a/lib/isc/netmgr/netmgr-int.h
|
||||||
|
+++ b/lib/isc/netmgr/netmgr-int.h
|
||||||
|
@@ -776,6 +776,7 @@ struct isc_nm {
|
||||||
|
isc_refcount_t references;
|
||||||
|
isc_mem_t *mctx;
|
||||||
|
int nworkers;
|
||||||
|
+ int nlisteners;
|
||||||
|
isc_mutex_t lock;
|
||||||
|
isc_condition_t wkstatecond;
|
||||||
|
isc_condition_t wkpausecond;
|
||||||
|
diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c
|
||||||
|
index b19d468..2310b4b 100644
|
||||||
|
--- a/lib/isc/netmgr/netmgr.c
|
||||||
|
+++ b/lib/isc/netmgr/netmgr.c
|
||||||
|
@@ -189,12 +189,12 @@ isc__nm_force_tid(int tid) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
-isc__nm_threadpool_initialize(uint32_t workers) {
|
||||||
|
+isc__nm_threadpool_initialize(uint32_t nworkers) {
|
||||||
|
char buf[11];
|
||||||
|
int r = uv_os_getenv("UV_THREADPOOL_SIZE", buf,
|
||||||
|
&(size_t){ sizeof(buf) });
|
||||||
|
if (r == UV_ENOENT) {
|
||||||
|
- snprintf(buf, sizeof(buf), "%" PRIu32, workers);
|
||||||
|
+ snprintf(buf, sizeof(buf), "%" PRIu32, nworkers);
|
||||||
|
uv_os_setenv("UV_THREADPOOL_SIZE", buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -212,11 +212,11 @@ isc__nm_threadpool_initialize(uint32_t workers) {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
-isc__netmgr_create(isc_mem_t *mctx, uint32_t workers, isc_nm_t **netmgrp) {
|
||||||
|
+isc__netmgr_create(isc_mem_t *mctx, uint32_t nworkers, isc_nm_t **netmgrp) {
|
||||||
|
isc_nm_t *mgr = NULL;
|
||||||
|
char name[32];
|
||||||
|
|
||||||
|
- REQUIRE(workers > 0);
|
||||||
|
+ REQUIRE(nworkers > 0);
|
||||||
|
|
||||||
|
#ifdef MAXIMAL_UV_VERSION
|
||||||
|
if (uv_version() > MAXIMAL_UV_VERSION) {
|
||||||
|
@@ -234,10 +234,13 @@ isc__netmgr_create(isc_mem_t *mctx, uint32_t workers, isc_nm_t **netmgrp) {
|
||||||
|
uv_version_string(), UV_VERSION_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
- isc__nm_threadpool_initialize(workers);
|
||||||
|
+ isc__nm_threadpool_initialize(nworkers);
|
||||||
|
|
||||||
|
mgr = isc_mem_get(mctx, sizeof(*mgr));
|
||||||
|
- *mgr = (isc_nm_t){ .nworkers = workers };
|
||||||
|
+ *mgr = (isc_nm_t){
|
||||||
|
+ .nworkers = nworkers * 2,
|
||||||
|
+ .nlisteners = nworkers,
|
||||||
|
+ };
|
||||||
|
|
||||||
|
isc_mem_attach(mctx, &mgr->mctx);
|
||||||
|
isc_mutex_init(&mgr->lock);
|
||||||
|
@@ -272,11 +275,12 @@ isc__netmgr_create(isc_mem_t *mctx, uint32_t workers, isc_nm_t **netmgrp) {
|
||||||
|
atomic_init(&mgr->keepalive, 30000);
|
||||||
|
atomic_init(&mgr->advertised, 30000);
|
||||||
|
|
||||||
|
- isc_barrier_init(&mgr->pausing, workers);
|
||||||
|
- isc_barrier_init(&mgr->resuming, workers);
|
||||||
|
+ isc_barrier_init(&mgr->pausing, mgr->nworkers);
|
||||||
|
+ isc_barrier_init(&mgr->resuming, mgr->nworkers);
|
||||||
|
|
||||||
|
- mgr->workers = isc_mem_get(mctx, workers * sizeof(isc__networker_t));
|
||||||
|
- for (size_t i = 0; i < workers; i++) {
|
||||||
|
+ mgr->workers = isc_mem_get(mctx,
|
||||||
|
+ mgr->nworkers * sizeof(isc__networker_t));
|
||||||
|
+ for (int i = 0; i < mgr->nworkers; i++) {
|
||||||
|
isc__networker_t *worker = &mgr->workers[i];
|
||||||
|
int r;
|
||||||
|
|
||||||
|
@@ -310,7 +314,7 @@ isc__netmgr_create(isc_mem_t *mctx, uint32_t workers, isc_nm_t **netmgrp) {
|
||||||
|
mgr->workers_running++;
|
||||||
|
isc_thread_create(nm_thread, &mgr->workers[i], &worker->thread);
|
||||||
|
|
||||||
|
- snprintf(name, sizeof(name), "isc-net-%04zu", i);
|
||||||
|
+ snprintf(name, sizeof(name), "isc-net-%04d", i);
|
||||||
|
isc_thread_setname(worker->thread, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -817,9 +821,15 @@ isc_nm_task_enqueue(isc_nm_t *nm, isc_task_t *task, int threadid) {
|
||||||
|
isc__networker_t *worker = NULL;
|
||||||
|
|
||||||
|
if (threadid == -1) {
|
||||||
|
- tid = (int)isc_random_uniform(nm->nworkers);
|
||||||
|
+ tid = (int)isc_random_uniform(nm->nlisteners);
|
||||||
|
+ } else if (threadid == ISC_NM_TASK_SLOW_OFFSET) {
|
||||||
|
+ tid = nm->nlisteners +
|
||||||
|
+ (int)isc_random_uniform(nm->nworkers - nm->nlisteners);
|
||||||
|
+ } else if (threadid < ISC_NM_TASK_SLOW_OFFSET) {
|
||||||
|
+ tid = nm->nlisteners + (ISC_NM_TASK_SLOW(threadid) %
|
||||||
|
+ (nm->nworkers - nm->nlisteners));
|
||||||
|
} else {
|
||||||
|
- tid = threadid % nm->nworkers;
|
||||||
|
+ tid = threadid % nm->nlisteners;
|
||||||
|
}
|
||||||
|
|
||||||
|
worker = &nm->workers[tid];
|
||||||
|
@@ -3778,7 +3788,7 @@ isc__nm_async_settlsctx(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||||
|
static void
|
||||||
|
set_tlsctx_workers(isc_nmsocket_t *listener, isc_tlsctx_t *tlsctx) {
|
||||||
|
/* Update the TLS context reference for every worker thread. */
|
||||||
|
- for (size_t i = 0; i < (size_t)listener->mgr->nworkers; i++) {
|
||||||
|
+ for (size_t i = 0; i < (size_t)listener->mgr->nlisteners; i++) {
|
||||||
|
isc__netievent__tlsctx_t *ievent =
|
||||||
|
isc__nm_get_netievent_settlsctx(listener->mgr, listener,
|
||||||
|
tlsctx);
|
||||||
|
diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c
|
||||||
|
index 2a644fe..16b53cc 100644
|
||||||
|
--- a/lib/isc/netmgr/tcp.c
|
||||||
|
+++ b/lib/isc/netmgr/tcp.c
|
||||||
|
@@ -341,7 +341,7 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
|
||||||
|
isc__nm_connectcb(sock, req, result, false);
|
||||||
|
} else {
|
||||||
|
isc__nmsocket_clearcb(sock);
|
||||||
|
- sock->tid = isc_random_uniform(mgr->nworkers);
|
||||||
|
+ sock->tid = isc_random_uniform(mgr->nlisteners);
|
||||||
|
isc__nm_connectcb(sock, req, result, true);
|
||||||
|
}
|
||||||
|
atomic_store(&sock->closed, true);
|
||||||
|
@@ -362,7 +362,7 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
|
||||||
|
isc__nm_put_netievent_tcpconnect(mgr, ievent);
|
||||||
|
} else {
|
||||||
|
atomic_init(&sock->active, false);
|
||||||
|
- sock->tid = isc_random_uniform(mgr->nworkers);
|
||||||
|
+ sock->tid = isc_random_uniform(mgr->nlisteners);
|
||||||
|
isc__nm_enqueue_ievent(&mgr->workers[sock->tid],
|
||||||
|
(isc__netievent_t *)ievent);
|
||||||
|
}
|
||||||
|
@@ -457,7 +457,7 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_sockaddr_t *iface,
|
||||||
|
isc__nmsocket_init(sock, mgr, isc_nm_tcplistener, iface);
|
||||||
|
|
||||||
|
atomic_init(&sock->rchildren, 0);
|
||||||
|
- sock->nchildren = mgr->nworkers;
|
||||||
|
+ sock->nchildren = mgr->nlisteners;
|
||||||
|
children_size = sock->nchildren * sizeof(sock->children[0]);
|
||||||
|
sock->children = isc_mem_get(mgr->mctx, children_size);
|
||||||
|
memset(sock->children, 0, children_size);
|
||||||
|
diff --git a/lib/isc/netmgr/tcpdns.c b/lib/isc/netmgr/tcpdns.c
|
||||||
|
index eda6aa6..46958d0 100644
|
||||||
|
--- a/lib/isc/netmgr/tcpdns.c
|
||||||
|
+++ b/lib/isc/netmgr/tcpdns.c
|
||||||
|
@@ -324,7 +324,7 @@ isc_nm_tcpdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
|
||||||
|
isc__nm_put_netievent_tcpdnsconnect(mgr, ievent);
|
||||||
|
} else {
|
||||||
|
atomic_init(&sock->active, false);
|
||||||
|
- sock->tid = isc_random_uniform(mgr->nworkers);
|
||||||
|
+ sock->tid = isc_random_uniform(mgr->nlisteners);
|
||||||
|
isc__nm_enqueue_ievent(&mgr->workers[sock->tid],
|
||||||
|
(isc__netievent_t *)ievent);
|
||||||
|
}
|
||||||
|
@@ -422,7 +422,7 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_sockaddr_t *iface,
|
||||||
|
isc__nmsocket_init(sock, mgr, isc_nm_tcpdnslistener, iface);
|
||||||
|
|
||||||
|
atomic_init(&sock->rchildren, 0);
|
||||||
|
- sock->nchildren = mgr->nworkers;
|
||||||
|
+ sock->nchildren = mgr->nlisteners;
|
||||||
|
children_size = sock->nchildren * sizeof(sock->children[0]);
|
||||||
|
sock->children = isc_mem_get(mgr->mctx, children_size);
|
||||||
|
memset(sock->children, 0, children_size);
|
||||||
|
diff --git a/lib/isc/netmgr/tlsdns.c b/lib/isc/netmgr/tlsdns.c
|
||||||
|
index d30e33f..40e6fc8 100644
|
||||||
|
--- a/lib/isc/netmgr/tlsdns.c
|
||||||
|
+++ b/lib/isc/netmgr/tlsdns.c
|
||||||
|
@@ -419,7 +419,7 @@ isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
|
||||||
|
isc__nm_put_netievent_tlsdnsconnect(mgr, ievent);
|
||||||
|
} else {
|
||||||
|
atomic_init(&sock->active, false);
|
||||||
|
- sock->tid = isc_random_uniform(mgr->nworkers);
|
||||||
|
+ sock->tid = isc_random_uniform(mgr->nlisteners);
|
||||||
|
isc__nm_enqueue_ievent(&mgr->workers[sock->tid],
|
||||||
|
(isc__netievent_t *)ievent);
|
||||||
|
}
|
||||||
|
@@ -532,7 +532,7 @@ isc_nm_listentlsdns(isc_nm_t *mgr, isc_sockaddr_t *iface,
|
||||||
|
isc__nmsocket_init(sock, mgr, isc_nm_tlsdnslistener, iface);
|
||||||
|
|
||||||
|
atomic_init(&sock->rchildren, 0);
|
||||||
|
- sock->nchildren = mgr->nworkers;
|
||||||
|
+ sock->nchildren = mgr->nlisteners;
|
||||||
|
children_size = sock->nchildren * sizeof(sock->children[0]);
|
||||||
|
sock->children = isc_mem_get(mgr->mctx, children_size);
|
||||||
|
memset(sock->children, 0, children_size);
|
||||||
|
diff --git a/lib/isc/netmgr/tlsstream.c b/lib/isc/netmgr/tlsstream.c
|
||||||
|
index 7b49071..a3fc6d2 100644
|
||||||
|
--- a/lib/isc/netmgr/tlsstream.c
|
||||||
|
+++ b/lib/isc/netmgr/tlsstream.c
|
||||||
|
@@ -1264,18 +1264,18 @@ isc__nm_tls_verify_tls_peer_result_string(const isc_nmhandle_t *handle) {
|
||||||
|
|
||||||
|
static void
|
||||||
|
tls_init_listener_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *ctx) {
|
||||||
|
- size_t nworkers;
|
||||||
|
+ size_t nlisteners;
|
||||||
|
|
||||||
|
REQUIRE(VALID_NM(listener->mgr));
|
||||||
|
REQUIRE(ctx != NULL);
|
||||||
|
|
||||||
|
- nworkers = (size_t)listener->mgr->nworkers;
|
||||||
|
- INSIST(nworkers > 0);
|
||||||
|
+ nlisteners = (size_t)listener->mgr->nlisteners;
|
||||||
|
+ INSIST(nlisteners > 0);
|
||||||
|
|
||||||
|
listener->tlsstream.listener_tls_ctx = isc_mem_get(
|
||||||
|
- listener->mgr->mctx, sizeof(isc_tlsctx_t *) * nworkers);
|
||||||
|
- listener->tlsstream.n_listener_tls_ctx = nworkers;
|
||||||
|
- for (size_t i = 0; i < nworkers; i++) {
|
||||||
|
+ listener->mgr->mctx, sizeof(isc_tlsctx_t *) * nlisteners);
|
||||||
|
+ listener->tlsstream.n_listener_tls_ctx = nlisteners;
|
||||||
|
+ for (size_t i = 0; i < nlisteners; i++) {
|
||||||
|
listener->tlsstream.listener_tls_ctx[i] = NULL;
|
||||||
|
isc_tlsctx_attach(ctx,
|
||||||
|
&listener->tlsstream.listener_tls_ctx[i]);
|
||||||
|
diff --git a/lib/isc/netmgr/udp.c b/lib/isc/netmgr/udp.c
|
||||||
|
index 476c799..661de96 100644
|
||||||
|
--- a/lib/isc/netmgr/udp.c
|
||||||
|
+++ b/lib/isc/netmgr/udp.c
|
||||||
|
@@ -157,14 +157,14 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_sockaddr_t *iface, isc_nm_recv_cb_t cb,
|
||||||
|
REQUIRE(VALID_NM(mgr));
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * We are creating mgr->nworkers duplicated sockets, one
|
||||||
|
+ * We are creating mgr->nlisteners duplicated sockets, one
|
||||||
|
* socket for each worker thread.
|
||||||
|
*/
|
||||||
|
sock = isc_mem_get(mgr->mctx, sizeof(isc_nmsocket_t));
|
||||||
|
isc__nmsocket_init(sock, mgr, isc_nm_udplistener, iface);
|
||||||
|
|
||||||
|
atomic_init(&sock->rchildren, 0);
|
||||||
|
- sock->nchildren = mgr->nworkers;
|
||||||
|
+ sock->nchildren = mgr->nlisteners;
|
||||||
|
children_size = sock->nchildren * sizeof(sock->children[0]);
|
||||||
|
sock->children = isc_mem_get(mgr->mctx, children_size);
|
||||||
|
memset(sock->children, 0, children_size);
|
||||||
|
@@ -1037,7 +1037,7 @@ isc_nm_udpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
|
||||||
|
isc__nm_put_netievent_udpconnect(mgr, event);
|
||||||
|
} else {
|
||||||
|
atomic_init(&sock->active, false);
|
||||||
|
- sock->tid = isc_random_uniform(mgr->nworkers);
|
||||||
|
+ sock->tid = isc_random_uniform(mgr->nlisteners);
|
||||||
|
isc__nm_enqueue_ievent(&mgr->workers[sock->tid],
|
||||||
|
(isc__netievent_t *)event);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
108
backport-CVE-2023-5517.patch
Normal file
108
backport-CVE-2023-5517.patch
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
From c73262493658cb8623927ef6cc2f023501f7e809 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Andrews <marka@isc.org>
|
||||||
|
Date: Tue, 10 Oct 2023 10:58:18 +1100
|
||||||
|
Subject: [PATCH] Save the correct result value to resume with
|
||||||
|
nxdomain-redirect
|
||||||
|
|
||||||
|
The wrong result value was being saved for resumption with
|
||||||
|
nxdomain-redirect when performing the fetch. This lead to an assert
|
||||||
|
when checking that RFC 1918 reverse queries where not leaking to
|
||||||
|
the global internet.
|
||||||
|
|
||||||
|
Conflict:NA
|
||||||
|
Reference:https://downloads.isc.org/isc/bind/9.18.24/patches/0002-CVE-2023-5517.patch
|
||||||
|
|
||||||
|
(cherry picked from commit 9d0fa07c5e7a39db89862a4f843d2190059afb4b)
|
||||||
|
---
|
||||||
|
lib/ns/query.c | 22 ++++++++++------------
|
||||||
|
1 file changed, 10 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/ns/query.c b/lib/ns/query.c
|
||||||
|
index c1e9148..61749c8 100644
|
||||||
|
--- a/lib/ns/query.c
|
||||||
|
+++ b/lib/ns/query.c
|
||||||
|
@@ -465,10 +465,10 @@ static void
|
||||||
|
query_addnxrrsetnsec(query_ctx_t *qctx);
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
-query_nxdomain(query_ctx_t *qctx, isc_result_t res);
|
||||||
|
+query_nxdomain(query_ctx_t *qctx, isc_result_t result);
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
-query_redirect(query_ctx_t *qctx);
|
||||||
|
+query_redirect(query_ctx_t *qctx, isc_result_t result);
|
||||||
|
|
||||||
|
static isc_result_t
|
||||||
|
query_ncache(query_ctx_t *qctx, isc_result_t result);
|
||||||
|
@@ -7718,8 +7718,7 @@ query_usestale(query_ctx_t *qctx, isc_result_t result) {
|
||||||
|
* result from the search.
|
||||||
|
*/
|
||||||
|
static isc_result_t
|
||||||
|
-query_gotanswer(query_ctx_t *qctx, isc_result_t res) {
|
||||||
|
- isc_result_t result = res;
|
||||||
|
+query_gotanswer(query_ctx_t *qctx, isc_result_t result) {
|
||||||
|
char errmsg[256];
|
||||||
|
|
||||||
|
CCTRACE(ISC_LOG_DEBUG(3), "query_gotanswer");
|
||||||
|
@@ -7795,7 +7794,7 @@ root_key_sentinel:
|
||||||
|
return (query_coveringnsec(qctx));
|
||||||
|
|
||||||
|
case DNS_R_NCACHENXDOMAIN:
|
||||||
|
- result = query_redirect(qctx);
|
||||||
|
+ result = query_redirect(qctx, result);
|
||||||
|
if (result != ISC_R_COMPLETE) {
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
@@ -9612,11 +9611,10 @@ query_addnxrrsetnsec(query_ctx_t *qctx) {
|
||||||
|
* Handle NXDOMAIN and empty wildcard responses.
|
||||||
|
*/
|
||||||
|
static isc_result_t
|
||||||
|
-query_nxdomain(query_ctx_t *qctx, isc_result_t res) {
|
||||||
|
+query_nxdomain(query_ctx_t *qctx, isc_result_t result) {
|
||||||
|
dns_section_t section;
|
||||||
|
uint32_t ttl;
|
||||||
|
- isc_result_t result = res;
|
||||||
|
- bool empty_wild = (res == DNS_R_EMPTYWILD);
|
||||||
|
+ bool empty_wild = (result == DNS_R_EMPTYWILD);
|
||||||
|
|
||||||
|
CCTRACE(ISC_LOG_DEBUG(3), "query_nxdomain");
|
||||||
|
|
||||||
|
@@ -9625,7 +9623,7 @@ query_nxdomain(query_ctx_t *qctx, isc_result_t res) {
|
||||||
|
INSIST(qctx->is_zone || REDIRECT(qctx->client));
|
||||||
|
|
||||||
|
if (!empty_wild) {
|
||||||
|
- result = query_redirect(qctx);
|
||||||
|
+ result = query_redirect(qctx, result);
|
||||||
|
if (result != ISC_R_COMPLETE) {
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
@@ -9713,7 +9711,7 @@ cleanup:
|
||||||
|
* redirecting, so query processing should continue past it.
|
||||||
|
*/
|
||||||
|
static isc_result_t
|
||||||
|
-query_redirect(query_ctx_t *qctx) {
|
||||||
|
+query_redirect(query_ctx_t *qctx, isc_result_t saved_result) {
|
||||||
|
isc_result_t result;
|
||||||
|
|
||||||
|
CCTRACE(ISC_LOG_DEBUG(3), "query_redirect");
|
||||||
|
@@ -9754,7 +9752,7 @@ query_redirect(query_ctx_t *qctx) {
|
||||||
|
SAVE(qctx->client->query.redirect.rdataset, qctx->rdataset);
|
||||||
|
SAVE(qctx->client->query.redirect.sigrdataset,
|
||||||
|
qctx->sigrdataset);
|
||||||
|
- qctx->client->query.redirect.result = DNS_R_NCACHENXDOMAIN;
|
||||||
|
+ qctx->client->query.redirect.result = saved_result;
|
||||||
|
dns_name_copy(qctx->fname, qctx->client->query.redirect.fname);
|
||||||
|
qctx->client->query.redirect.authoritative =
|
||||||
|
qctx->authoritative;
|
||||||
|
@@ -10415,7 +10413,7 @@ query_coveringnsec(query_ctx_t *qctx) {
|
||||||
|
* We now have the proof that we have an NXDOMAIN. Apply
|
||||||
|
* NXDOMAIN redirection if configured.
|
||||||
|
*/
|
||||||
|
- result = query_redirect(qctx);
|
||||||
|
+ result = query_redirect(qctx, DNS_R_COVERINGNSEC);
|
||||||
|
if (result != ISC_R_COMPLETE) {
|
||||||
|
redirected = true;
|
||||||
|
goto cleanup;
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
38
backport-CVE-2023-5679.patch
Normal file
38
backport-CVE-2023-5679.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
From 7db2796507127b40e2f091dafb842c6a7e86b9a8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Andrews <marka@isc.org>
|
||||||
|
Date: Thu, 12 Oct 2023 12:01:46 +1100
|
||||||
|
Subject: [PATCH] Restore dns64 state during serve-stale processing
|
||||||
|
|
||||||
|
If we are in the process of looking for the A records as part of
|
||||||
|
dns64 processing and the server-stale timeout triggers, redo the
|
||||||
|
dns64 changes that had been made to the orignal qctx.
|
||||||
|
|
||||||
|
Conflict:NA
|
||||||
|
Reference:https://downloads.isc.org/isc/bind/9.18.24/patches/0003-CVE-2023-5679.patch
|
||||||
|
|
||||||
|
(cherry picked from commit 1fcc483df13e049b96f620e515f0d4d45f3680b7)
|
||||||
|
---
|
||||||
|
lib/ns/query.c | 7 +++++++
|
||||||
|
1 file changed, 7 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/lib/ns/query.c b/lib/ns/query.c
|
||||||
|
index 61749c8..40e1232 100644
|
||||||
|
--- a/lib/ns/query.c
|
||||||
|
+++ b/lib/ns/query.c
|
||||||
|
@@ -6228,6 +6228,13 @@ query_lookup_stale(ns_client_t *client) {
|
||||||
|
query_ctx_t qctx;
|
||||||
|
|
||||||
|
qctx_init(client, NULL, client->query.qtype, &qctx);
|
||||||
|
+ if (DNS64(client)) {
|
||||||
|
+ qctx.qtype = qctx.type = dns_rdatatype_a;
|
||||||
|
+ qctx.dns64 = true;
|
||||||
|
+ }
|
||||||
|
+ if (DNS64EXCLUDE(client)) {
|
||||||
|
+ qctx.dns64_exclude = true;
|
||||||
|
+ }
|
||||||
|
dns_db_attach(client->view->cachedb, &qctx.db);
|
||||||
|
client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK;
|
||||||
|
client->query.dboptions |= DNS_DBFIND_STALETIMEOUT;
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
12
bind.spec
12
bind.spec
@ -29,7 +29,7 @@ Summary: The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) serv
|
|||||||
Name: bind
|
Name: bind
|
||||||
License: MPLv2.0
|
License: MPLv2.0
|
||||||
Version: 9.18.21
|
Version: 9.18.21
|
||||||
Release: 1
|
Release: 2
|
||||||
Epoch: 32
|
Epoch: 32
|
||||||
Url: https://www.isc.org/downloads/bind/
|
Url: https://www.isc.org/downloads/bind/
|
||||||
#
|
#
|
||||||
@ -60,6 +60,10 @@ Source46: named-setup-rndc.service
|
|||||||
Source48: setup-named-softhsm.sh
|
Source48: setup-named-softhsm.sh
|
||||||
Source49: named-chroot.files
|
Source49: named-chroot.files
|
||||||
|
|
||||||
|
Patch6000:backport-CVE-2023-4408.patch
|
||||||
|
Patch6001:backport-CVE-2023-5517.patch
|
||||||
|
Patch6002:backport-CVE-2023-5679.patch
|
||||||
|
Patch6003:backport-CVE-2023-50387-CVE-2023-50868.patch
|
||||||
# Common patches
|
# Common patches
|
||||||
|
|
||||||
%{?systemd_ordering}
|
%{?systemd_ordering}
|
||||||
@ -899,6 +903,12 @@ fi;
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Mar 19 2024 chengyechun<chengyechun1@huawei.com> - 32:9.18.21-2
|
||||||
|
- Type:CVE
|
||||||
|
- CVE:CVE-2023-4408 CVE-2023-5517 CVE-2023-5679 CVE-2023-50387 CVE-2023-50868
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:fix CVE-2023-4408 CVE-2023-5517 CVE-2023-5679 CVE-2023-50387 CVE-2023-50868
|
||||||
|
|
||||||
* Sun Feb 04 2024 zhanghao<zhanghao383@huawei.com> - 32:9.18.21-1
|
* Sun Feb 04 2024 zhanghao<zhanghao383@huawei.com> - 32:9.18.21-1
|
||||||
- Type:requirement
|
- Type:requirement
|
||||||
- CVE:NA
|
- CVE:NA
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user