]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Process NSID and DNS COOKIE options when returning BADVERS
authorMark Andrews <marka@isc.org>
Fri, 25 Oct 2024 03:43:03 +0000 (14:43 +1100)
committerMark Andrews <marka@isc.org>
Tue, 15 Apr 2025 03:13:20 +0000 (03:13 +0000)
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 0d9cab15551be8cdc06969c39eaf851732cda51d)

lib/ns/client.c

index 0b38ffc078820e6e2f557eb615f1e11ffc3bb3d5..048a6c72b737319435dbdfbac7ea779e71517919 100644 (file)
@@ -1550,17 +1550,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);
@@ -1572,6 +1561,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)) {
@@ -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_statscounter_edns0in);
        client->attributes |= NS_CLIENTATTR_WANTOPT;