diff --git a/SOURCES/bind-9.11-CVE-2020-8622.patch b/SOURCES/bind-9.11-CVE-2020-8622.patch new file mode 100644 index 0000000..74e8225 --- /dev/null +++ b/SOURCES/bind-9.11-CVE-2020-8622.patch @@ -0,0 +1,57 @@ +From c5a9fd85a19a63f88a5f17c7e6d074ee22364093 Mon Sep 17 00:00:00 2001 +From: Petr Mensik +Date: Tue, 18 Aug 2020 10:53:33 +0200 +Subject: [PATCH] Fix CVE-2020-8622 + +5476. [security] It was possible to trigger an assertion failure when + verifying the response to a TSIG-signed request. + (CVE-2020-8622) [GL #2028] +--- + lib/dns/message.c | 24 +++++++++++++----------- + 1 file changed, 13 insertions(+), 11 deletions(-) + +diff --git a/lib/dns/message.c b/lib/dns/message.c +index d9e341a..7c813a5 100644 +--- a/lib/dns/message.c ++++ b/lib/dns/message.c +@@ -1712,6 +1712,19 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source, + msg->header_ok = 0; + msg->question_ok = 0; + ++ if ((options & DNS_MESSAGEPARSE_CLONEBUFFER) == 0) { ++ isc_buffer_usedregion(&origsource, &msg->saved); ++ } else { ++ msg->saved.length = isc_buffer_usedlength(&origsource); ++ msg->saved.base = isc_mem_get(msg->mctx, msg->saved.length); ++ if (msg->saved.base == NULL) { ++ return (ISC_R_NOMEMORY); ++ } ++ memmove(msg->saved.base, isc_buffer_base(&origsource), ++ msg->saved.length); ++ msg->free_saved = 1; ++ } ++ + isc_buffer_remainingregion(source, &r); + if (r.length < DNS_MESSAGE_HEADERLEN) + return (ISC_R_UNEXPECTEDEND); +@@ -1787,17 +1800,6 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source, + } + + truncated: +- if ((options & DNS_MESSAGEPARSE_CLONEBUFFER) == 0) +- isc_buffer_usedregion(&origsource, &msg->saved); +- else { +- msg->saved.length = isc_buffer_usedlength(&origsource); +- msg->saved.base = isc_mem_get(msg->mctx, msg->saved.length); +- if (msg->saved.base == NULL) +- return (ISC_R_NOMEMORY); +- memmove(msg->saved.base, isc_buffer_base(&origsource), +- msg->saved.length); +- msg->free_saved = 1; +- } + + if (ret == ISC_R_UNEXPECTEDEND && ignore_tc) + return (DNS_R_RECOVERABLE); +-- +2.26.2 + diff --git a/SOURCES/bind-9.11-CVE-2020-8623.patch b/SOURCES/bind-9.11-CVE-2020-8623.patch new file mode 100644 index 0000000..ee368d0 --- /dev/null +++ b/SOURCES/bind-9.11-CVE-2020-8623.patch @@ -0,0 +1,400 @@ +From e8b7be1e1ff3e11bc8d592c3c8d6a0f0d69e9947 Mon Sep 17 00:00:00 2001 +From: Petr Mensik +Date: Tue, 18 Aug 2020 10:54:39 +0200 +Subject: [PATCH] Fix CVE-2020-8623 + +5480. [security] When BIND 9 was compiled with native PKCS#11 support, it + was possible to trigger an assertion failure in code + determining the number of bits in the PKCS#11 RSA public + key with a specially crafted packet. (CVE-2020-8623) + [GL #2037] +--- + lib/dns/pkcs11dh_link.c | 15 ++++++- + lib/dns/pkcs11dsa_link.c | 8 +++- + lib/dns/pkcs11rsa_link.c | 79 +++++++++++++++++++++++++-------- + lib/isc/include/pk11/internal.h | 3 +- + lib/isc/pk11.c | 61 ++++++++++++++++--------- + 5 files changed, 121 insertions(+), 45 deletions(-) + +diff --git a/lib/dns/pkcs11dh_link.c b/lib/dns/pkcs11dh_link.c +index e2b60ea..4cd8e32 100644 +--- a/lib/dns/pkcs11dh_link.c ++++ b/lib/dns/pkcs11dh_link.c +@@ -748,6 +748,7 @@ pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) { + CK_BYTE *prime = NULL, *base = NULL, *pub = NULL; + CK_ATTRIBUTE *attr; + int special = 0; ++ unsigned int bits; + isc_result_t result; + + isc_buffer_remainingregion(data, &r); +@@ -852,7 +853,11 @@ pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) { + pub = r.base; + isc_region_consume(&r, publen); + +- key->key_size = pk11_numbits(prime, plen_); ++ result = pk11_numbits(prime, plen_, &bits); ++ if (result != ISC_R_SUCCESS) { ++ goto cleanup; ++ } ++ key->key_size = bits; + + dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3); + if (dh->repr == NULL) +@@ -1012,6 +1017,7 @@ pkcs11dh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { + dst_private_t priv; + isc_result_t ret; + int i; ++ unsigned int bits; + pk11_object_t *dh = NULL; + CK_ATTRIBUTE *attr; + isc_mem_t *mctx; +@@ -1082,7 +1088,12 @@ pkcs11dh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { + + attr = pk11_attribute_bytype(dh, CKA_PRIME); + INSIST(attr != NULL); +- key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); ++ ++ ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); ++ if (ret != ISC_R_SUCCESS) { ++ goto err; ++ } ++ key->key_size = bits; + + return (ISC_R_SUCCESS); + +diff --git a/lib/dns/pkcs11dsa_link.c b/lib/dns/pkcs11dsa_link.c +index 12d707a..24d4c14 100644 +--- a/lib/dns/pkcs11dsa_link.c ++++ b/lib/dns/pkcs11dsa_link.c +@@ -983,6 +983,7 @@ pkcs11dsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { + dst_private_t priv; + isc_result_t ret; + int i; ++ unsigned int bits; + pk11_object_t *dsa = NULL; + CK_ATTRIBUTE *attr; + isc_mem_t *mctx = key->mctx; +@@ -1072,7 +1073,12 @@ pkcs11dsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { + + attr = pk11_attribute_bytype(dsa, CKA_PRIME); + INSIST(attr != NULL); +- key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); ++ ++ ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); ++ if (ret != ISC_R_SUCCESS) { ++ goto err; ++ } ++ key->key_size = bits; + + return (ISC_R_SUCCESS); + +diff --git a/lib/dns/pkcs11rsa_link.c b/lib/dns/pkcs11rsa_link.c +index 6c280bf..86e136a 100644 +--- a/lib/dns/pkcs11rsa_link.c ++++ b/lib/dns/pkcs11rsa_link.c +@@ -337,6 +337,7 @@ pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, + key->key_alg == DST_ALG_RSASHA256 || + key->key_alg == DST_ALG_RSASHA512); + #endif ++ REQUIRE(maxbits <= RSA_MAX_PUBEXP_BITS); + + /* + * Reject incorrect RSA key lengths. +@@ -381,6 +382,7 @@ pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, + for (attr = pk11_attribute_first(rsa); + attr != NULL; + attr = pk11_attribute_next(rsa, attr)) ++ { + switch (attr->type) { + case CKA_MODULUS: + INSIST(keyTemplate[5].type == attr->type); +@@ -401,12 +403,16 @@ pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, + memmove(keyTemplate[6].pValue, attr->pValue, + attr->ulValueLen); + keyTemplate[6].ulValueLen = attr->ulValueLen; +- if (pk11_numbits(attr->pValue, +- attr->ulValueLen) > maxbits && +- maxbits != 0) ++ unsigned int bits; ++ ret = pk11_numbits(attr->pValue, attr->ulValueLen, ++ &bits); ++ if (ret != ISC_R_SUCCESS || ++ (bits > maxbits && maxbits != 0)) { + DST_RET(DST_R_VERIFYFAILURE); ++ } + break; + } ++ } + pk11_ctx->object = CK_INVALID_HANDLE; + pk11_ctx->ontoken = false; + PK11_RET(pkcs_C_CreateObject, +@@ -1086,6 +1092,7 @@ pkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) { + keyTemplate[5].ulValueLen = attr->ulValueLen; + break; + case CKA_PUBLIC_EXPONENT: ++ unsigned int bits; + INSIST(keyTemplate[6].type == attr->type); + keyTemplate[6].pValue = isc_mem_get(dctx->mctx, + attr->ulValueLen); +@@ -1094,10 +1101,12 @@ pkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) { + memmove(keyTemplate[6].pValue, attr->pValue, + attr->ulValueLen); + keyTemplate[6].ulValueLen = attr->ulValueLen; +- if (pk11_numbits(attr->pValue, +- attr->ulValueLen) +- > RSA_MAX_PUBEXP_BITS) ++ ret = pk11_numbits(attr->pValue, attr->ulValueLen, ++ &bits); ++ if (ret != ISC_R_SUCCESS || bits > RSA_MAX_PUBEXP_BITS) ++ { + DST_RET(DST_R_VERIFYFAILURE); ++ } + break; + } + pk11_ctx->object = CK_INVALID_HANDLE; +@@ -1475,6 +1484,8 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { + CK_BYTE *exponent = NULL, *modulus = NULL; + CK_ATTRIBUTE *attr; + unsigned int length; ++ unsigned int bits; ++ isc_result_t ret = ISC_R_SUCCESS; + + isc_buffer_remainingregion(data, &r); + if (r.length == 0) +@@ -1492,9 +1503,7 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { + + if (e_bytes == 0) { + if (r.length < 2) { +- isc_safe_memwipe(rsa, sizeof(*rsa)); +- isc_mem_put(key->mctx, rsa, sizeof(*rsa)); +- return (DST_R_INVALIDPUBLICKEY); ++ DST_RET(DST_R_INVALIDPUBLICKEY); + } + e_bytes = (*r.base) << 8; + isc_region_consume(&r, 1); +@@ -1503,16 +1512,18 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { + } + + if (r.length < e_bytes) { +- isc_safe_memwipe(rsa, sizeof(*rsa)); +- isc_mem_put(key->mctx, rsa, sizeof(*rsa)); +- return (DST_R_INVALIDPUBLICKEY); ++ DST_RET(DST_R_INVALIDPUBLICKEY); + } + exponent = r.base; + isc_region_consume(&r, e_bytes); + modulus = r.base; + mod_bytes = r.length; + +- key->key_size = pk11_numbits(modulus, mod_bytes); ++ ret = pk11_numbits(modulus, mod_bytes, &bits); ++ if (ret != ISC_R_SUCCESS) { ++ goto err; ++ } ++ key->key_size = bits; + + isc_buffer_forward(data, length); + +@@ -1562,9 +1573,12 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { + rsa->repr, + rsa->attrcnt * sizeof(*attr)); + } ++ ret = ISC_R_NOMEMORY; ++ ++ err: + isc_safe_memwipe(rsa, sizeof(*rsa)); + isc_mem_put(key->mctx, rsa, sizeof(*rsa)); +- return (ISC_R_NOMEMORY); ++ return (ret); + } + + static isc_result_t +@@ -1743,6 +1757,7 @@ pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label, + pk11_object_t *pubrsa; + pk11_context_t *pk11_ctx = NULL; + isc_result_t ret; ++ unsigned int bits; + + if (label == NULL) + return (DST_R_NOENGINE); +@@ -1829,7 +1844,11 @@ pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label, + + attr = pk11_attribute_bytype(rsa, CKA_MODULUS); + INSIST(attr != NULL); +- key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); ++ ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); ++ if (ret != ISC_R_SUCCESS) { ++ goto err; ++ } ++ key->key_size = bits; + + return (ISC_R_SUCCESS); + +@@ -1915,6 +1934,7 @@ pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { + CK_ATTRIBUTE *attr; + isc_mem_t *mctx = key->mctx; + const char *engine = NULL, *label = NULL; ++ unsigned int bits; + + /* read private key file */ + ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); +@@ -2058,12 +2078,22 @@ pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { + + attr = pk11_attribute_bytype(rsa, CKA_MODULUS); + INSIST(attr != NULL); +- key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); ++ ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); ++ if (ret != ISC_R_SUCCESS) { ++ goto err; ++ } ++ key->key_size = bits; + + attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); + INSIST(attr != NULL); +- if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS) ++ ++ ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); ++ if (ret != ISC_R_SUCCESS) { ++ goto err; ++ } ++ if (bits > RSA_MAX_PUBEXP_BITS) { + DST_RET(ISC_R_RANGE); ++ } + + dst__privstruct_free(&priv, mctx); + isc_safe_memwipe(&priv, sizeof(priv)); +@@ -2098,6 +2128,7 @@ pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label, + pk11_context_t *pk11_ctx = NULL; + isc_result_t ret; + unsigned int i; ++ unsigned int bits; + + UNUSED(pin); + +@@ -2192,12 +2223,22 @@ pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label, + + attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); + INSIST(attr != NULL); +- if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS) ++ ++ ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); ++ if (ret != ISC_R_SUCCESS) { ++ goto err; ++ } ++ if (bits > RSA_MAX_PUBEXP_BITS) { + DST_RET(ISC_R_RANGE); ++ } + + attr = pk11_attribute_bytype(rsa, CKA_MODULUS); + INSIST(attr != NULL); +- key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); ++ ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); ++ if (ret != ISC_R_SUCCESS) { ++ goto err; ++ } ++ key->key_size = bits; + + pk11_return_session(pk11_ctx); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); +diff --git a/lib/isc/include/pk11/internal.h b/lib/isc/include/pk11/internal.h +index 603712a..b9680bc 100644 +--- a/lib/isc/include/pk11/internal.h ++++ b/lib/isc/include/pk11/internal.h +@@ -27,7 +27,8 @@ void pk11_mem_put(void *ptr, size_t size); + + CK_SLOT_ID pk11_get_best_token(pk11_optype_t optype); + +-unsigned int pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt); ++isc_result_t ++pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt, unsigned int *bits); + + CK_ATTRIBUTE *pk11_attribute_first(const pk11_object_t *obj); + +diff --git a/lib/isc/pk11.c b/lib/isc/pk11.c +index 4b85527..9c450da 100644 +--- a/lib/isc/pk11.c ++++ b/lib/isc/pk11.c +@@ -982,13 +982,15 @@ pk11_get_best_token(pk11_optype_t optype) { + return (token->slotid); + } + +-unsigned int +-pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt) { ++isc_result_t ++pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt, unsigned int *bits) { + unsigned int bitcnt, i; + CK_BYTE top; + +- if (bytecnt == 0) +- return (0); ++ if (bytecnt == 0) { ++ *bits = 0; ++ return (ISC_R_SUCCESS); ++ } + bitcnt = bytecnt * 8; + for (i = 0; i < bytecnt; i++) { + top = data[i]; +@@ -996,26 +998,41 @@ pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt) { + bitcnt -= 8; + continue; + } +- if (top & 0x80) +- return (bitcnt); +- if (top & 0x40) +- return (bitcnt - 1); +- if (top & 0x20) +- return (bitcnt - 2); +- if (top & 0x10) +- return (bitcnt - 3); +- if (top & 0x08) +- return (bitcnt - 4); +- if (top & 0x04) +- return (bitcnt - 5); +- if (top & 0x02) +- return (bitcnt - 6); +- if (top & 0x01) +- return (bitcnt - 7); ++ if (top & 0x80) { ++ *bits = bitcnt; ++ return (ISC_R_SUCCESS); ++ } ++ if (top & 0x40) { ++ *bits = bitcnt - 1; ++ return (ISC_R_SUCCESS); ++ } ++ if (top & 0x20) { ++ *bits = bitcnt - 2; ++ return (ISC_R_SUCCESS); ++ } ++ if (top & 0x10) { ++ *bits = bitcnt - 3; ++ return (ISC_R_SUCCESS); ++ } ++ if (top & 0x08) { ++ *bits = bitcnt - 4; ++ return (ISC_R_SUCCESS); ++ } ++ if (top & 0x04) { ++ *bits = bitcnt - 5; ++ return (ISC_R_SUCCESS); ++ } ++ if (top & 0x02) { ++ *bits = bitcnt - 6; ++ return (ISC_R_SUCCESS); ++ } ++ if (top & 0x01) { ++ *bits = bitcnt - 7; ++ return (ISC_R_SUCCESS); ++ } + break; + } +- INSIST(0); +- ISC_UNREACHABLE(); ++ return (ISC_R_RANGE); + } + + CK_ATTRIBUTE * +-- +2.26.2 + diff --git a/SOURCES/bind-9.11-CVE-2020-8624-test.patch b/SOURCES/bind-9.11-CVE-2020-8624-test.patch new file mode 100644 index 0000000..288d916 --- /dev/null +++ b/SOURCES/bind-9.11-CVE-2020-8624-test.patch @@ -0,0 +1,152 @@ +From 221fb11e658e7dea1be6dbfd25e149f2d131e4fb Mon Sep 17 00:00:00 2001 +From: Mark Andrews +Date: Wed, 29 Jul 2020 23:36:03 +1000 +Subject: [PATCH] Add a test for update-policy 'subdomain' + +The new test checks that 'update-policy subdomain' is properly enforced. + +(cherry picked from commit 393e8f643c02215fa4e6d4edf67be7d77085da0e) + +Add a test for update-policy 'zonesub' + +The new test checks that 'update-policy zonesub' is properly enforced. + +(cherry picked from commit 58e560beb50873c699f3431cf57e215dc645d7aa) +--- + bin/tests/system/nsupdate/ns1/named.conf.in | 12 +++++ + bin/tests/system/nsupdate/tests.sh | 60 +++++++++++++++++++-- + 2 files changed, 68 insertions(+), 4 deletions(-) + +diff --git a/bin/tests/system/nsupdate/ns1/named.conf.in b/bin/tests/system/nsupdate/ns1/named.conf.in +index 26b6b7c9ab..540a984842 100644 +--- a/bin/tests/system/nsupdate/ns1/named.conf.in ++++ b/bin/tests/system/nsupdate/ns1/named.conf.in +@@ -36,6 +36,16 @@ key altkey { + secret "1234abcd8765"; + }; + ++key restricted.example.nil { ++ algorithm hmac-md5; ++ secret "1234abcd8765"; ++}; ++ ++key zonesub-key.example.nil { ++ algorithm hmac-md5; ++ secret "1234subk8765"; ++}; ++ + include "ddns.key"; + + zone "example.nil" { +@@ -44,7 +54,9 @@ zone "example.nil" { + check-integrity no; + check-mx ignore; + update-policy { ++ grant zonesub-key.example.nil zonesub TXT; + grant ddns-key.example.nil subdomain example.nil ANY; ++ grant restricted.example.nil subdomain restricted.example.nil ANY; + }; + allow-transfer { any; }; + }; +diff --git a/bin/tests/system/nsupdate/tests.sh b/bin/tests/system/nsupdate/tests.sh +index b08c5220e7..5f09e8c5bf 100755 +--- a/bin/tests/system/nsupdate/tests.sh ++++ b/bin/tests/system/nsupdate/tests.sh +@@ -428,7 +428,7 @@ EOF + # this also proves that the server is still running. + $DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocmd +norec example.\ + @10.53.0.3 nsec3param > dig.out.ns3.$n || ret=1 +-grep "ANSWER: 0" dig.out.ns3.$n > /dev/null || ret=1 ++grep "ANSWER: 0," dig.out.ns3.$n > /dev/null || ret=1 + grep "flags:[^;]* aa[ ;]" dig.out.ns3.$n > /dev/null || ret=1 + [ $ret = 0 ] || { echo_i "failed"; status=1; } + +@@ -443,7 +443,7 @@ EOF + + $DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocmd +norec nsec3param.test.\ + @10.53.0.3 nsec3param > dig.out.ns3.$n || ret=1 +-grep "ANSWER: 1" dig.out.ns3.$n > /dev/null || ret=1 ++grep "ANSWER: 1," dig.out.ns3.$n > /dev/null || ret=1 + grep "3600.*NSEC3PARAM" dig.out.ns3.$n > /dev/null || ret=1 + grep "flags:[^;]* aa[ ;]" dig.out.ns3.$n > /dev/null || ret=1 + [ $ret = 0 ] || { echo_i "failed"; status=1; } +@@ -460,7 +460,7 @@ EOF + _ret=1 + for i in 0 1 2 3 4 5 6 7 8 9; do + $DIG $DIGOPTS +tcp +norec +time=1 +tries=1 @10.53.0.3 nsec3param.test. NSEC3PARAM > dig.out.ns3.$n || _ret=1 +- if grep "ANSWER: 2" dig.out.ns3.$n > /dev/null; then ++ if grep "ANSWER: 2," dig.out.ns3.$n > /dev/null; then + _ret=0 + break + fi +@@ -485,7 +485,7 @@ EOF + _ret=1 + for i in 0 1 2 3 4 5 6 7 8 9; do + $DIG $DIGOPTS +tcp +norec +time=1 +tries=1 @10.53.0.3 nsec3param.test. NSEC3PARAM > dig.out.ns3.$n || _ret=1 +- if grep "ANSWER: 1" dig.out.ns3.$n > /dev/null; then ++ if grep "ANSWER: 1," dig.out.ns3.$n > /dev/null; then + _ret=0 + break + fi +@@ -631,6 +631,58 @@ then + echo_i "failed"; status=1 + fi + ++n=`expr $n + 1` ++ret=0 ++echo_i "check that 'update-policy subdomain' is properly enforced ($n)" ++# "restricted.example.nil" matches "grant ... subdomain restricted.example.nil" ++# and thus this UPDATE should succeed. ++$NSUPDATE -d < nsupdate.out1-$n 2>&1 || ret=1 ++server 10.53.0.1 ${PORT} ++key restricted.example.nil 1234abcd8765 ++update add restricted.example.nil 0 IN TXT everywhere. ++send ++END ++$DIG $DIGOPTS +tcp @10.53.0.1 restricted.example.nil TXT > dig.out.1.test$n || ret=1 ++grep "TXT.*everywhere" dig.out.1.test$n > /dev/null || ret=1 ++# "example.nil" does not match "grant ... subdomain restricted.example.nil" and ++# thus this UPDATE should fail. ++$NSUPDATE -d < nsupdate.out2-$n 2>&1 && ret=1 ++server 10.53.0.1 ${PORT} ++key restricted.example.nil 1234abcd8765 ++update add example.nil 0 IN TXT everywhere. ++send ++END ++$DIG $DIGOPTS +tcp @10.53.0.1 example.nil TXT > dig.out.2.test$n || ret=1 ++grep "TXT.*everywhere" dig.out.2.test$n > /dev/null && ret=1 ++[ $ret = 0 ] || { echo_i "failed"; status=1; } ++ ++n=`expr $n + 1` ++ret=0 ++echo_i "check that 'update-policy zonesub' is properly enforced ($n)" ++# grant zonesub-key.example.nil zonesub TXT; ++# the A record update should be rejected as it is not in the type list ++$NSUPDATE -d < nsupdate.out1-$n 2>&1 && ret=1 ++server 10.53.0.1 ${PORT} ++key zonesub-key.example.nil 1234subk8765 ++update add zonesub.example.nil 0 IN A 1.2.3.4 ++send ++END ++$DIG $DIGOPTS +tcp @10.53.0.1 zonesub.example.nil A > dig.out.1.test$n || ret=1 ++grep "status: REFUSED" nsupdate.out1-$n > /dev/null || ret=1 ++grep "ANSWER: 0," dig.out.1.test$n > /dev/null || ret=1 ++# the TXT record update should be accepted as it is in the type list ++$NSUPDATE -d < nsupdate.out2-$n 2>&1 || ret=1 ++server 10.53.0.1 ${PORT} ++key zonesub-key.example.nil 1234subk8765 ++update add zonesub.example.nil 0 IN TXT everywhere. ++send ++END ++$DIG $DIGOPTS +tcp @10.53.0.1 zonesub.example.nil TXT > dig.out.2.test$n || ret=1 ++grep "status: REFUSED" nsupdate.out2-$n > /dev/null && ret=1 ++grep "ANSWER: 1," dig.out.2.test$n > /dev/null || ret=1 ++grep "TXT.*everywhere" dig.out.2.test$n > /dev/null || ret=1 ++[ $ret = 0 ] || { echo_i "failed"; status=1; } ++ + n=`expr $n + 1` + ret=0 + echo_i "check that changes to the DNSKEY RRset TTL do not have side effects ($n)" +-- +2.26.2 + diff --git a/SOURCES/bind-9.11-CVE-2020-8624.patch b/SOURCES/bind-9.11-CVE-2020-8624.patch new file mode 100644 index 0000000..225298d --- /dev/null +++ b/SOURCES/bind-9.11-CVE-2020-8624.patch @@ -0,0 +1,32 @@ +From e2aae621408c7622d094f13a67b928f911a2793b Mon Sep 17 00:00:00 2001 +From: Petr Mensik +Date: Tue, 18 Aug 2020 10:55:50 +0200 +Subject: [PATCH] Fix CVE-2020-8624 + +5481. [security] "update-policy" rules of type "subdomain" were + incorrectly treated as "zonesub" rules, which allowed + keys used in "subdomain" rules to update names outside + of the specified subdomains. The problem was fixed by + making sure "subdomain" rules are again processed as + described in the ARM. (CVE-2020-8624) [GL #2055] +--- + bin/named/zoneconf.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c +index 55f191b..b77a07c 100644 +--- a/bin/named/zoneconf.c ++++ b/bin/named/zoneconf.c +@@ -239,7 +239,8 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone, + + str = cfg_obj_asstring(matchtype); + CHECK(dns_ssu_mtypefromstring(str, &mtype)); +- if (mtype == dns_ssumatchtype_subdomain) { ++ if (mtype == dns_ssumatchtype_subdomain && ++ strcasecmp(str, "zonesub") == 0) { + usezone = true; + } + +-- +2.26.2 + diff --git a/SPECS/bind.spec b/SPECS/bind.spec index b30d44b..2597fe2 100644 --- a/SPECS/bind.spec +++ b/SPECS/bind.spec @@ -65,7 +65,7 @@ Summary: The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) serv Name: bind License: MPLv2.0 Version: 9.11.20 -Release: 4%{?PATCHVER:.%{PATCHVER}}%{?PREVER:.%{PREVER}}%{?dist} +Release: 5%{?PATCHVER:.%{PATCHVER}}%{?PREVER:.%{PREVER}}%{?dist} Epoch: 32 Url: http://www.isc.org/products/BIND/ # @@ -156,6 +156,13 @@ Patch175:bind-9.11-json-c.patch Patch177:bind-9.11-serve-stale.patch Patch178:bind-9.11-dhcp-time-monotonic.patch Patch179:bind-9.11-rh1859454.patch +# https://gitlab.isc.org/isc-projects/bind9/commit/ae9af802b5e7169c55cc5ef04dcfbded351c743d +Patch180:bind-9.11-CVE-2020-8622.patch +# https://gitlab.isc.org/isc-projects/bind9/commit/0660b022fc6130dda2a27d6164fc7decdcabce8d +Patch181:bind-9.11-CVE-2020-8623.patch +# https://gitlab.isc.org/isc-projects/bind9/commit/8e919cf6e47c4f52612069ac0868f8caa5089e74 +Patch182:bind-9.11-CVE-2020-8624.patch +Patch183:bind-9.11-CVE-2020-8624-test.patch # SDB patches Patch11: bind-9.3.2b2-sdbsrc.patch @@ -515,6 +522,10 @@ are used for building ISC DHCP. %patch177 -p1 -b .serve-stale %patch178 -p1 -b .time-monotonic %patch179 -p1 -b .rh1859454 +%patch180 -p1 -b .CVE-2020-8622 +%patch181 -p1 -b .CVE-2020-8623 +%patch182 -p1 -b .CVE-2020-8624 +%patch183 -p1 -b .CVE-2020-8624-test mkdir lib/dns/tests/testdata/dstrandom cp -a %{SOURCE50} lib/dns/tests/testdata/dstrandom/random.data @@ -1523,6 +1534,12 @@ rm -rf ${RPM_BUILD_ROOT} %changelog +* Tue Aug 18 2020 Petr Menšík - 32:9.11.20-5 +- Fix tsig-request verify (CVE-2020-8622) +- Prevent PKCS11 daemon crash on crafted packet (CVE-2020-8623) +- Correct update-policy type subdomain to match documentation (CVE-2020-8624) +- Include available test + * Wed Jul 22 2020 Petr Menšík - 32:9.11.20-4 - Prevent crash on dstlib initialization failure (#1859454)