diff --git a/CHANGES b/CHANGES index 2798122996..6619a41975 100644 --- a/CHANGES +++ b/CHANGES @@ -43,7 +43,9 @@ 5617. [placeholder] -5616. [placeholder] +5616. [security] named crashed when a DNAME record placed in the ANSWER + section during DNAME chasing turned out to be the final + answer to a client query. (CVE-2021-25215) [GL #2540] 5615. [security] Insufficient IXFR checks could result in named serving a zone without an SOA record at the apex, leading to a diff --git a/doc/notes/notes-current.rst b/doc/notes/notes-current.rst index b559bccf92..ca8344ac80 100644 --- a/doc/notes/notes-current.rst +++ b/doc/notes/notes-current.rst @@ -20,6 +20,15 @@ Security Fixes ISC would like to thank Greg Kuechle of SaskTel for bringing this vulnerability to our attention. [GL #2467] +- ``named`` crashed when a DNAME record placed in the ANSWER section + during DNAME chasing turned out to be the final answer to a client + query. (CVE-2021-25215) + + ISC would like to thank `Siva Kakarla`_ for bringing this + vulnerability to our attention. [GL #2540] + +.. _Siva Kakarla: https://github.com/sivakesava1 + Known Issues ~~~~~~~~~~~~ diff --git a/lib/ns/query.c b/lib/ns/query.c index 97b8a9d5a2..f15101ced2 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -8173,10 +8173,16 @@ query_respond(query_ctx_t *qctx) { query_addnoqnameproof(qctx); /* - * We shouldn't ever fail to add 'rdataset' - * because it's already in the answer. + * 'qctx->rdataset' will only be non-NULL here if the ANSWER section of + * the message to be sent to the client already contains an RRset with + * the same owner name and the same type as 'qctx->rdataset'. This + * should never happen, with one exception: when chasing DNAME records, + * one of the DNAME records placed in the ANSWER section may turn out + * to be the final answer to the client's query, but we have no way of + * knowing that until now. In such a case, 'qctx->rdataset' will be + * freed later, so we do not need to free it here. */ - INSIST(qctx->rdataset == NULL); + INSIST(qctx->rdataset == NULL || qctx->qtype == dns_rdatatype_dname); query_addauth(qctx);