From e85702ce5be33d7c07eff6487c6bb4730165f331 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Sat, 8 Dec 2012 14:05:32 +1100 Subject: [PATCH] 3438. [bug] Don't accept unknown data escape in quotes. [RT #32031] Squashed commit of the following: commit 7ad3daade513c94a1c92ee7c91c112f161d13ef4 Author: Mark Andrews Date: Mon Dec 3 15:03:44 2012 +1100 look at the second token to determine if a TXT record in of unknown format or not commit 7df32138462646f6aee84ffa56d02ac24ec8d672 Author: Mark Andrews Date: Mon Dec 3 12:42:18 2012 +1100 '"\#"' was incorrectly being treated as a unknown data escape sequence. --- CHANGES | 2 ++ bin/tests/system/unknown/ns1/example-in.db | 2 ++ bin/tests/system/unknown/tests.sh | 14 +++++++++++ lib/dns/include/dns/rdata.h | 1 + lib/dns/rdata.c | 29 +++++++++++++++++++--- lib/dns/rdata/generic/txt_16.c | 7 ++++++ 6 files changed, 51 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 3a249bc05b..5f8fd487fe 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +3438. [bug] Don't accept unknown data escape in quotes. [RT #32031] + 3437. [bug] isc_buffer_init -> isc_buffer_constinit to initialise buffers with constant data. [RT #32064] diff --git a/bin/tests/system/unknown/ns1/example-in.db b/bin/tests/system/unknown/ns1/example-in.db index c8485d364c..63ea80deb8 100644 --- a/bin/tests/system/unknown/ns1/example-in.db +++ b/bin/tests/system/unknown/ns1/example-in.db @@ -53,6 +53,8 @@ txt4 CLASS1 TYPE16 "hello" txt5 TXT \# 6 0568656C6C6F txt6 TYPE16 \# 6 0568656C6C6F txt7 IN TXT \# 6 0568656C6C6F +txt8 IN TXT "\#" 2 0145 +txt9 IN TXT \# text unk1 TYPE123 \# 1 00 unk2 CLASS1 TYPE123 \# 1 00 diff --git a/bin/tests/system/unknown/tests.sh b/bin/tests/system/unknown/tests.sh index 14bb8539fd..f0f8e8fbcb 100644 --- a/bin/tests/system/unknown/tests.sh +++ b/bin/tests/system/unknown/tests.sh @@ -172,5 +172,19 @@ diff large.out dig.out > /dev/null || { ret=1 ; echo "I: diff failed"; } [ $ret = 0 ] || echo "I: failed" status=`expr $status + $ret` +echo "I:check that '"'"\\#"'"' is not treated as the unknown escape sequence" +ret=0 +DIG $DIGOPTS @10.53.0.1 +tcp +short txt8.example txt > dig.out +echo '"#" "2" "0145"' | diff - dig.out || ret=1 +[ $ret = 0 ] || echo "I: failed" +status=`expr $status + $ret` + +echo "I:check that '"'TXT \# text'"' is not treated as the unknown escape sequence" +ret=0 +DIG $DIGOPTS @10.53.0.1 +tcp +short txt9.example txt > dig.out +echo '"#" "text"' | diff - dig.out || ret=1 +[ $ret = 0 ] || echo "I: failed" +status=`expr $status + $ret` + echo "I:exit status: $status" exit $status diff --git a/lib/dns/include/dns/rdata.h b/lib/dns/include/dns/rdata.h index 2c7b2730fb..89ecaf8006 100644 --- a/lib/dns/include/dns/rdata.h +++ b/lib/dns/include/dns/rdata.h @@ -177,6 +177,7 @@ struct dns_rdata { #define DNS_RDATA_CHECKREVERSE DNS_NAME_CHECKREVERSE #define DNS_RDATA_CHECKMX DNS_NAME_CHECKMX #define DNS_RDATA_CHECKMXFAIL DNS_NAME_CHECKMXFAIL +#define DNS_RDATA_UNKNOWNESCAPE 0x80000000 /*** *** Initialization diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c index 6e7c8a229e..ed32d65538 100644 --- a/lib/dns/rdata.c +++ b/lib/dns/rdata.c @@ -621,6 +621,7 @@ dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass, void (*callback)(dns_rdatacallbacks_t *, const char *, ...); isc_result_t tresult; size_t length; + isc_boolean_t unknown; REQUIRE(origin == NULL || dns_name_isabsolute(origin) == ISC_TRUE); if (rdata != NULL) { @@ -648,13 +649,33 @@ dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass, return (result); } - if (strcmp(DNS_AS_STR(token), "\\#") == 0) - result = unknown_fromtext(rdclass, type, lexer, mctx, target); - else { + unknown = ISC_FALSE; + if (token.type == isc_tokentype_string && + strcmp(DNS_AS_STR(token), "\\#") == 0) { + /* + * If this is a TXT record '\#' could be a escaped '#'. + * Look to see if the next token is a number and if so + * treat it as a unknown record format. + */ + if (type == dns_rdatatype_txt) { + result = isc_lex_getmastertoken(lexer, &token, + isc_tokentype_number, + ISC_FALSE); + if (result == ISC_R_SUCCESS) + isc_lex_ungettoken(lexer, &token); + } + + if (result == ISC_R_SUCCESS) { + unknown = ISC_TRUE; + result = unknown_fromtext(rdclass, type, lexer, + mctx, target); + } else + options |= DNS_RDATA_UNKNOWNESCAPE; + } else isc_lex_ungettoken(lexer, &token); + if (!unknown) FROMTEXTSWITCH - } /* * Consume to end of line / file. diff --git a/lib/dns/rdata/generic/txt_16.c b/lib/dns/rdata/generic/txt_16.c index c49864e670..be889808a0 100644 --- a/lib/dns/rdata/generic/txt_16.c +++ b/lib/dns/rdata/generic/txt_16.c @@ -38,6 +38,13 @@ fromtext_txt(ARGS_FROMTEXT) { UNUSED(callbacks); strings = 0; + if ((options & DNS_RDATA_UNKNOWNESCAPE) != 0) { + isc_textregion_t r; + DE_CONST("#", r.base); + r.length = 1; + RETTOK(txt_fromtext(&r, target)); + strings++; + } for (;;) { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,