mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 06:55:30 +00:00
fix another message parsing regression
The fix for CVE-2023-4408 introduced a regression in the message parser, which could cause a crash if an rdata type that can only occur in the question was found in another section. Use 'dns__message_putassociatedrdataset()' instead of 'dns__message_puttemprdataset()', because after calling the 'dns_rdatalist_tordataset()' function earlier the 'rdataset' is associated.
This commit is contained in:
committed by
Michał Kępień
parent
4c19d35614
commit
510f1de8a6
@@ -1250,6 +1250,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx,
|
|||||||
isedns = false;
|
isedns = false;
|
||||||
issigzero = false;
|
issigzero = false;
|
||||||
istsig = false;
|
istsig = false;
|
||||||
|
found_rdataset = NULL;
|
||||||
|
|
||||||
name = NULL;
|
name = NULL;
|
||||||
dns_message_gettempname(msg, &name);
|
dns_message_gettempname(msg, &name);
|
||||||
@@ -1394,10 +1395,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx,
|
|||||||
* Then put the meta-class back into the finished rdata.
|
* Then put the meta-class back into the finished rdata.
|
||||||
*/
|
*/
|
||||||
rdata = newrdata(msg);
|
rdata = newrdata(msg);
|
||||||
if (rdata == NULL) {
|
|
||||||
result = ISC_R_NOMEMORY;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if (msg->opcode == dns_opcode_update &&
|
if (msg->opcode == dns_opcode_update &&
|
||||||
update(sectionid, rdclass))
|
update(sectionid, rdclass))
|
||||||
{
|
{
|
||||||
@@ -1549,7 +1546,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx,
|
|||||||
* the question section, fail.
|
* the question section, fail.
|
||||||
*/
|
*/
|
||||||
if (dns_rdatatype_questiononly(rdtype)) {
|
if (dns_rdatatype_questiononly(rdtype)) {
|
||||||
dns_message_puttemprdataset(msg, &rdataset);
|
|
||||||
DO_ERROR(DNS_R_FORMERR);
|
DO_ERROR(DNS_R_FORMERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1600,18 +1596,17 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx,
|
|||||||
/* Free the rdataset we used as the key */
|
/* Free the rdataset we used as the key */
|
||||||
dns__message_putassociatedrdataset(msg,
|
dns__message_putassociatedrdataset(msg,
|
||||||
&rdataset);
|
&rdataset);
|
||||||
rdataset = found_rdataset;
|
|
||||||
|
|
||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
|
rdataset = found_rdataset;
|
||||||
|
|
||||||
if (!dns_rdatatype_issingleton(rdtype)) {
|
if (!dns_rdatatype_issingleton(rdtype)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_rdata_t *first;
|
|
||||||
dns_rdatalist_fromrdataset(rdataset,
|
dns_rdatalist_fromrdataset(rdataset,
|
||||||
&rdatalist);
|
&rdatalist);
|
||||||
first = ISC_LIST_HEAD(rdatalist->rdata);
|
dns_rdata_t *first =
|
||||||
|
ISC_LIST_HEAD(rdatalist->rdata);
|
||||||
INSIST(first != NULL);
|
INSIST(first != NULL);
|
||||||
if (dns_rdata_compare(rdata, first) != 0) {
|
if (dns_rdata_compare(rdata, first) != 0) {
|
||||||
DO_ERROR(DNS_R_FORMERR);
|
DO_ERROR(DNS_R_FORMERR);
|
||||||
@@ -1656,7 +1651,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx,
|
|||||||
dns_rcode_t ercode;
|
dns_rcode_t ercode;
|
||||||
|
|
||||||
msg->opt = rdataset;
|
msg->opt = rdataset;
|
||||||
rdataset = NULL;
|
|
||||||
ercode = (dns_rcode_t)((msg->opt->ttl &
|
ercode = (dns_rcode_t)((msg->opt->ttl &
|
||||||
DNS_MESSAGE_EDNSRCODE_MASK) >>
|
DNS_MESSAGE_EDNSRCODE_MASK) >>
|
||||||
20);
|
20);
|
||||||
@@ -1667,7 +1661,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx,
|
|||||||
msg->sig0 = rdataset;
|
msg->sig0 = rdataset;
|
||||||
msg->sig0name = name;
|
msg->sig0name = name;
|
||||||
msg->sigstart = recstart;
|
msg->sigstart = recstart;
|
||||||
rdataset = NULL;
|
|
||||||
free_name = false;
|
free_name = false;
|
||||||
} else if (istsig) {
|
} else if (istsig) {
|
||||||
msg->tsig = rdataset;
|
msg->tsig = rdataset;
|
||||||
@@ -1677,9 +1670,9 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx,
|
|||||||
* Windows doesn't like TSIG names to be compressed.
|
* Windows doesn't like TSIG names to be compressed.
|
||||||
*/
|
*/
|
||||||
msg->tsigname->attributes.nocompress = true;
|
msg->tsigname->attributes.nocompress = true;
|
||||||
rdataset = NULL;
|
|
||||||
free_name = false;
|
free_name = false;
|
||||||
}
|
}
|
||||||
|
rdataset = NULL;
|
||||||
|
|
||||||
if (seen_problem) {
|
if (seen_problem) {
|
||||||
if (free_name) {
|
if (free_name) {
|
||||||
@@ -1688,8 +1681,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx,
|
|||||||
free_name = false;
|
free_name = false;
|
||||||
}
|
}
|
||||||
INSIST(!free_name);
|
INSIST(!free_name);
|
||||||
|
|
||||||
rdataset = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1711,6 +1702,9 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
if (rdataset != NULL && rdataset != found_rdataset) {
|
||||||
|
dns__message_putassociatedrdataset(msg, &rdataset);
|
||||||
|
}
|
||||||
if (free_name) {
|
if (free_name) {
|
||||||
dns_message_puttempname(msg, &name);
|
dns_message_puttempname(msg, &name);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user