mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 14:35:26 +00:00
1193. [bug] dig +besteffort parsing didn't handle packet
truncation. dns_message_parse() has new flag DNS_MESSAGE_IGNORETRUNCATION.
This commit is contained in:
4
CHANGES
4
CHANGES
@@ -19,7 +19,9 @@
|
|||||||
1194. [bug] Not all duplicate zone definitions were being detected
|
1194. [bug] Not all duplicate zone definitions were being detected
|
||||||
at the named.conf checking stage. [RT #2431]
|
at the named.conf checking stage. [RT #2431]
|
||||||
|
|
||||||
1193. [bug] Best effort parsing didn't handle packet truncation.
|
1193. [bug] dig +besteffort parsing didn't handle packet
|
||||||
|
truncation. dns_message_parse() has new flag
|
||||||
|
DNS_MESSAGE_IGNORETRUNCATION.
|
||||||
|
|
||||||
1192. [bug] The seconds fields in LOC records were restricted
|
1192. [bug] The seconds fields in LOC records were restricted
|
||||||
to three decimal places. More decimal places should
|
to three decimal places. More decimal places should
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: dighost.c,v 1.238 2001/11/30 01:58:39 gson Exp $ */
|
/* $Id: dighost.c,v 1.239 2002/02/12 02:10:30 marka Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Notice to programmers: Do not use this code as an example of how to
|
* Notice to programmers: Do not use this code as an example of how to
|
||||||
@@ -2195,8 +2195,10 @@ recv_done(isc_task_t *task, isc_event_t *event) {
|
|||||||
|
|
||||||
debug("before parse starts");
|
debug("before parse starts");
|
||||||
parseflags = DNS_MESSAGEPARSE_PRESERVEORDER;
|
parseflags = DNS_MESSAGEPARSE_PRESERVEORDER;
|
||||||
if (l->besteffort)
|
if (l->besteffort) {
|
||||||
parseflags |= DNS_MESSAGEPARSE_BESTEFFORT;
|
parseflags |= DNS_MESSAGEPARSE_BESTEFFORT;
|
||||||
|
parseflags |= DNS_MESSAGEPARSE_IGNORETRUNCATION;
|
||||||
|
}
|
||||||
result = dns_message_parse(msg, b, parseflags);
|
result = dns_message_parse(msg, b, parseflags);
|
||||||
if (result == DNS_R_RECOVERABLE) {
|
if (result == DNS_R_RECOVERABLE) {
|
||||||
printf(";; Warning: Message parser reports malformed "
|
printf(";; Warning: Message parser reports malformed "
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: message.h,v 1.106 2002/01/22 09:07:26 bwelling Exp $ */
|
/* $Id: message.h,v 1.107 2002/02/12 02:10:33 marka Exp $ */
|
||||||
|
|
||||||
#ifndef DNS_MESSAGE_H
|
#ifndef DNS_MESSAGE_H
|
||||||
#define DNS_MESSAGE_H 1
|
#define DNS_MESSAGE_H 1
|
||||||
@@ -153,6 +153,8 @@ typedef int dns_messagetextflag_t;
|
|||||||
occurs */
|
occurs */
|
||||||
#define DNS_MESSAGEPARSE_CLONEBUFFER 0x0004 /* save a copy of the
|
#define DNS_MESSAGEPARSE_CLONEBUFFER 0x0004 /* save a copy of the
|
||||||
source buffer */
|
source buffer */
|
||||||
|
#define DNS_MESSAGEPARSE_IGNORETRUNCATION 0x0008 /* trucation errors are
|
||||||
|
* not fatal. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Control behavior of rendering
|
* Control behavior of rendering
|
||||||
@@ -401,6 +403,9 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
|
|||||||
* not be considered FORMERRs. If the entire message can be parsed, it
|
* not be considered FORMERRs. If the entire message can be parsed, it
|
||||||
* will be returned and DNS_R_RECOVERABLE will be returned.
|
* will be returned and DNS_R_RECOVERABLE will be returned.
|
||||||
*
|
*
|
||||||
|
* If DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete
|
||||||
|
* RR's as possible, DNS_R_RECOVERABLE will be returned.
|
||||||
|
*
|
||||||
* OPT and TSIG records are always handled specially, regardless of the
|
* OPT and TSIG records are always handled specially, regardless of the
|
||||||
* 'preserve_order' setting.
|
* 'preserve_order' setting.
|
||||||
*
|
*
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: message.c,v 1.206 2002/02/11 02:03:23 marka Exp $ */
|
/* $Id: message.c,v 1.207 2002/02/12 02:10:32 marka Exp $ */
|
||||||
|
|
||||||
/***
|
/***
|
||||||
*** Imports
|
*** Imports
|
||||||
@@ -942,7 +942,6 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||||||
isc_boolean_t free_name;
|
isc_boolean_t free_name;
|
||||||
isc_boolean_t best_effort;
|
isc_boolean_t best_effort;
|
||||||
isc_boolean_t seen_problem;
|
isc_boolean_t seen_problem;
|
||||||
isc_buffer_t save = *source;
|
|
||||||
|
|
||||||
section = &msg->sections[DNS_SECTION_QUESTION];
|
section = &msg->sections[DNS_SECTION_QUESTION];
|
||||||
|
|
||||||
@@ -954,7 +953,6 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||||||
rdatalist = NULL;
|
rdatalist = NULL;
|
||||||
|
|
||||||
for (count = 0; count < msg->counts[DNS_SECTION_QUESTION]; count++) {
|
for (count = 0; count < msg->counts[DNS_SECTION_QUESTION]; count++) {
|
||||||
save = *source;
|
|
||||||
name = isc_mempool_get(msg->namepool);
|
name = isc_mempool_get(msg->namepool);
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
@@ -1074,10 +1072,6 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (result == ISC_R_UNEXPECTEDEND && best_effort) {
|
|
||||||
*source = save;
|
|
||||||
result = DNS_R_RECOVERABLE;
|
|
||||||
}
|
|
||||||
if (rdataset != NULL) {
|
if (rdataset != NULL) {
|
||||||
INSIST(!dns_rdataset_isassociated(rdataset));
|
INSIST(!dns_rdataset_isassociated(rdataset));
|
||||||
isc_mempool_put(msg->rdspool, rdataset);
|
isc_mempool_put(msg->rdspool, rdataset);
|
||||||
@@ -1122,7 +1116,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||||||
isc_boolean_t free_name, free_rdataset;
|
isc_boolean_t free_name, free_rdataset;
|
||||||
isc_boolean_t preserve_order, best_effort, seen_problem;
|
isc_boolean_t preserve_order, best_effort, seen_problem;
|
||||||
isc_boolean_t issigzero;
|
isc_boolean_t issigzero;
|
||||||
isc_buffer_t save = *source;
|
|
||||||
|
|
||||||
preserve_order = ISC_TF(options & DNS_MESSAGEPARSE_PRESERVEORDER);
|
preserve_order = ISC_TF(options & DNS_MESSAGEPARSE_PRESERVEORDER);
|
||||||
best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
|
best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
|
||||||
@@ -1138,7 +1131,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||||||
skip_type_search = ISC_FALSE;
|
skip_type_search = ISC_FALSE;
|
||||||
free_name = ISC_FALSE;
|
free_name = ISC_FALSE;
|
||||||
free_rdataset = ISC_FALSE;
|
free_rdataset = ISC_FALSE;
|
||||||
save = *source;
|
|
||||||
|
|
||||||
name = isc_mempool_get(msg->namepool);
|
name = isc_mempool_get(msg->namepool);
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
@@ -1482,10 +1474,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (result == ISC_R_UNEXPECTEDEND && best_effort) {
|
|
||||||
*source = save;
|
|
||||||
result = DNS_R_RECOVERABLE;
|
|
||||||
}
|
|
||||||
if (free_name)
|
if (free_name)
|
||||||
isc_mempool_put(msg->namepool, name);
|
isc_mempool_put(msg->namepool, name);
|
||||||
if (free_rdataset)
|
if (free_rdataset)
|
||||||
@@ -1504,12 +1492,14 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
|
|||||||
isc_uint16_t tmpflags;
|
isc_uint16_t tmpflags;
|
||||||
isc_buffer_t origsource;
|
isc_buffer_t origsource;
|
||||||
isc_boolean_t seen_problem;
|
isc_boolean_t seen_problem;
|
||||||
|
isc_boolean_t ignore_tc;
|
||||||
|
|
||||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||||
REQUIRE(source != NULL);
|
REQUIRE(source != NULL);
|
||||||
REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
|
REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
|
||||||
|
|
||||||
seen_problem = ISC_FALSE;
|
seen_problem = ISC_FALSE;
|
||||||
|
ignore_tc = ISC_TF(options & DNS_MESSAGEPARSE_IGNORETRUNCATION);
|
||||||
|
|
||||||
origsource = *source;
|
origsource = *source;
|
||||||
|
|
||||||
@@ -1541,6 +1531,8 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
|
|||||||
dns_decompress_setmethods(&dctx, DNS_COMPRESS_GLOBAL14);
|
dns_decompress_setmethods(&dctx, DNS_COMPRESS_GLOBAL14);
|
||||||
|
|
||||||
ret = getquestions(source, msg, &dctx, options);
|
ret = getquestions(source, msg, &dctx, options);
|
||||||
|
if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
|
||||||
|
goto truncated;
|
||||||
if (ret == DNS_R_RECOVERABLE) {
|
if (ret == DNS_R_RECOVERABLE) {
|
||||||
seen_problem = ISC_TRUE;
|
seen_problem = ISC_TRUE;
|
||||||
ret = ISC_R_SUCCESS;
|
ret = ISC_R_SUCCESS;
|
||||||
@@ -1550,6 +1542,8 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
|
|||||||
msg->question_ok = 1;
|
msg->question_ok = 1;
|
||||||
|
|
||||||
ret = getsection(source, msg, &dctx, DNS_SECTION_ANSWER, options);
|
ret = getsection(source, msg, &dctx, DNS_SECTION_ANSWER, options);
|
||||||
|
if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
|
||||||
|
goto truncated;
|
||||||
if (ret == DNS_R_RECOVERABLE) {
|
if (ret == DNS_R_RECOVERABLE) {
|
||||||
seen_problem = ISC_TRUE;
|
seen_problem = ISC_TRUE;
|
||||||
ret = ISC_R_SUCCESS;
|
ret = ISC_R_SUCCESS;
|
||||||
@@ -1558,6 +1552,8 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
|
|||||||
return (ret);
|
return (ret);
|
||||||
|
|
||||||
ret = getsection(source, msg, &dctx, DNS_SECTION_AUTHORITY, options);
|
ret = getsection(source, msg, &dctx, DNS_SECTION_AUTHORITY, options);
|
||||||
|
if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
|
||||||
|
goto truncated;
|
||||||
if (ret == DNS_R_RECOVERABLE) {
|
if (ret == DNS_R_RECOVERABLE) {
|
||||||
seen_problem = ISC_TRUE;
|
seen_problem = ISC_TRUE;
|
||||||
ret = ISC_R_SUCCESS;
|
ret = ISC_R_SUCCESS;
|
||||||
@@ -1566,6 +1562,8 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
|
|||||||
return (ret);
|
return (ret);
|
||||||
|
|
||||||
ret = getsection(source, msg, &dctx, DNS_SECTION_ADDITIONAL, options);
|
ret = getsection(source, msg, &dctx, DNS_SECTION_ADDITIONAL, options);
|
||||||
|
if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
|
||||||
|
goto truncated;
|
||||||
if (ret == DNS_R_RECOVERABLE) {
|
if (ret == DNS_R_RECOVERABLE) {
|
||||||
seen_problem = ISC_TRUE;
|
seen_problem = ISC_TRUE;
|
||||||
ret = ISC_R_SUCCESS;
|
ret = ISC_R_SUCCESS;
|
||||||
@@ -1581,6 +1579,7 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
|
|||||||
r.length);
|
r.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
truncated:
|
||||||
if ((options & DNS_MESSAGEPARSE_CLONEBUFFER) == 0)
|
if ((options & DNS_MESSAGEPARSE_CLONEBUFFER) == 0)
|
||||||
isc_buffer_usedregion(&origsource, &msg->saved);
|
isc_buffer_usedregion(&origsource, &msg->saved);
|
||||||
else {
|
else {
|
||||||
@@ -1593,6 +1592,8 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
|
|||||||
msg->free_saved = 1;
|
msg->free_saved = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
|
||||||
|
return (DNS_R_RECOVERABLE);
|
||||||
if (seen_problem == ISC_TRUE)
|
if (seen_problem == ISC_TRUE)
|
||||||
return (DNS_R_RECOVERABLE);
|
return (DNS_R_RECOVERABLE);
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
|
Reference in New Issue
Block a user