From: Mark Andrews Date: Fri, 25 Oct 2024 03:43:03 +0000 (+1100) Subject: Process NSID and DNS COOKIE options when returning BADVERS X-Git-Tag: v9.21.8~26^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0d9cab15551be8cdc06969c39eaf851732cda51d;p=thirdparty%2Fbind9.git 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. --- diff --git a/lib/ns/client.c b/lib/ns/client.c index 3eba3c61d90..214e440440f 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -1580,17 +1580,6 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) { * XXXRTH need library support for this! */ 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 */ result = dns_rdataset_first(opt); @@ -1602,6 +1591,17 @@ process_opt(ns_client_t *client, dns_rdataset_t *opt) { while (isc_buffer_remaininglength(&optbuf) >= 4) { optcode = 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) { case DNS_OPT_NSID: if (!WANTNSID(client)) { @@ -1683,6 +1683,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_statscounter_edns0in); client->attributes |= NS_CLIENTATTR_WANTOPT;