2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

Process NSID and DNS COOKIE options when returning BADVERS

This will help identify the broken server if we happen to break
EDNS version negotiation.  It will also help protect the client
from spoofed BADVERSION responses.

(cherry picked from commit 0d9cab1555)
This commit is contained in:
Mark Andrews
2024-10-25 14:43:03 +11:00
parent 745a9ab15f
commit 71875eb25a

View File

@@ -1550,17 +1550,6 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) {
* XXXRTH need library support for this! * XXXRTH need library support for this!
*/ */
client->ednsversion = (opt->ttl & 0x00FF0000) >> 16; client->ednsversion = (opt->ttl & 0x00FF0000) >> 16;
if (client->ednsversion > DNS_EDNS_VERSION) {
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_badednsver);
result = ns_client_addopt(client, client->message,
&client->opt);
if (result == ISC_R_SUCCESS) {
result = DNS_R_BADVERS;
}
ns_client_error(client, result);
return result;
}
/* Check for NSID request */ /* Check for NSID request */
result = dns_rdataset_first(opt); result = dns_rdataset_first(opt);
@@ -1572,6 +1561,17 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) {
while (isc_buffer_remaininglength(&optbuf) >= 4) { while (isc_buffer_remaininglength(&optbuf) >= 4) {
optcode = isc_buffer_getuint16(&optbuf); optcode = isc_buffer_getuint16(&optbuf);
optlen = isc_buffer_getuint16(&optbuf); optlen = isc_buffer_getuint16(&optbuf);
/*
* When returning BADVERSION, only process
* DNS_OPT_NSID or DNS_OPT_COOKIE options.
*/
if (client->ednsversion > DNS_EDNS_VERSION &&
optcode != DNS_OPT_NSID &&
optcode != DNS_OPT_COOKIE)
{
isc_buffer_forward(&optbuf, optlen);
continue;
}
switch (optcode) { switch (optcode) {
case DNS_OPT_NSID: case DNS_OPT_NSID:
if (!WANTNSID(client)) { if (!WANTNSID(client)) {
@@ -1643,6 +1643,18 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) {
} }
} }
if (client->ednsversion > DNS_EDNS_VERSION) {
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_badednsver);
result = ns_client_addopt(client, client->message,
&client->opt);
if (result == ISC_R_SUCCESS) {
result = DNS_R_BADVERS;
}
ns_client_error(client, result);
return result;
}
ns_stats_increment(client->manager->sctx->nsstats, ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_edns0in); ns_statscounter_edns0in);
client->attributes |= NS_CLIENTATTR_WANTOPT; client->attributes |= NS_CLIENTATTR_WANTOPT;