response when there is a malformed EDNS option.
[RT #39647]
4153. [bug] Check that non significant ECS bits are zero on
receipt. [RT #39647]
+4154. [bug] A OPT record should be included with the FORMERR
+ response when there is a malformed EDNS option.
+ [RT #39647]
+
+4153. [bug] Check that non significant ECS bits are zero on
+ receipt. [RT #39647]
+
4151. [bug] 'rndc flush' could cause a deadlock. [RT #39835]
4150. [bug] win32: listen-on-v6 { any; }; was not working. Apply
* Parsing the request failed. Send a response
* (typically FORMERR or SERVFAIL).
*/
+ if (result == DNS_R_OPTERR)
+ (void)client_addopt(client);
ns_client_error(client, result);
goto cleanup;
}
--- /dev/null
+00 00 00 00 00 01 00 00 00 00 00 01
+00 00 01 00 02
+00 00 29 10 00 00 00 00 00 00 04 00 08 00 00
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
+rm -f badoptoption.out
rm -f nametoolong.out
-rm -f twoquestions.out
rm -f noquestions.out
+rm -f twoquestions.out
echo "I:failed"; status=`expr $status + 1`;
fi
+echo "I:bad OPT option"
+$PERL formerr.pl -a 10.53.0.1 -p 5300 badoptoption > badoptoption.out
+ans=`grep got: badoptoption.out`
+if [ "${ans}" != "got: 00008001000100000000000100000100020000291000000000000000" ];
+then
+ echo "I:failed"; status=`expr $status + 1`;
+fi
+
echo "I:exit status: $status"
exit $status
#define DNS_R_NTACOVERED (ISC_RESULTCLASS_DNS + 110)
#define DNS_R_BADCDS (ISC_RESULTCLASS_DNS + 111)
#define DNS_R_BADCDNSKEY (ISC_RESULTCLASS_DNS + 112)
+#define DNS_R_OPTERR (ISC_RESULTCLASS_DNS + 113)
-#define DNS_R_NRESULTS 113 /*%< Number of results */
+#define DNS_R_NRESULTS 114 /*%< Number of results */
/*
* DNS wire format rcodes.
isc_uint8_t addrbytes;
if (length < 4)
- return (DNS_R_FORMERR);
+ return (DNS_R_OPTERR);
family = uint16_fromregion(&sregion);
isc_region_consume(&sregion, 2);
addrlen = uint8_fromregion(&sregion);
switch (family) {
case 1:
if (addrlen > 32U || scope > 32U)
- return (DNS_R_FORMERR);
+ return (DNS_R_OPTERR);
break;
case 2:
if (addrlen > 128U || scope > 128U)
- return (DNS_R_FORMERR);
+ return (DNS_R_OPTERR);
break;
}
addrbytes = (addrlen + 7) / 8;
if (addrbytes + 4 != length)
- return (DNS_R_FORMERR);
+ return (DNS_R_OPTERR);
+
+ if (addrbytes != 0U && (addrlen % 8) != 0) {
+ isc_uint8_t bits = ~0 << (8 - (addrlen % 8));
+ bits &= sregion.base[addrbytes - 1];
+ if (bits != sregion.base[addrbytes - 1])
+ return (DNS_R_OPTERR);
+ }
isc_region_consume(&sregion, addrbytes);
break;
}
* Request has zero length. Response is 32 bits.
*/
if (length != 0 && length != 4)
- return (DNS_R_FORMERR);
+ return (DNS_R_OPTERR);
isc_region_consume(&sregion, length);
break;
default:
"not dynamic", /*%< 108 DNS_R_NOTDYNAMIC */
"bad EUI", /*%< 109 DNS_R_BADEUI */
- "covered by negative trust anchor", /*%< 110 DNS_R_NTACOVERED */
+ "covered by negative trust anchor", /*%< 110 DNS_R_NTACOVERED */
"bad CDS", /*%< 111 DNS_R_BADCSD */
- "bad CDNSKEY" /*%< 112 DNS_R_BADCDNSKEY */
+ "bad CDNSKEY", /*%< 112 DNS_R_BADCDNSKEY */
+ "malformed OPT option" /*%< 113 DNS_R_OPTERR */
};
static const char *rcode_text[DNS_R_NRCODERESULTS] = {
*/
return ((dns_rcode_t)((result) & 0xFFF));
}
+
/*
* Try to supply an appropriate rcode.
*/
case DNS_R_TSIGERRORSET:
case DNS_R_UNKNOWN:
case DNS_R_NAMETOOLONG:
+ case DNS_R_OPTERR:
rcode = dns_rcode_formerr;
break;
case DNS_R_DISALLOWED: