]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Check opcode of messages returned by dns_request_getresponse
authorMark Andrews <marka@isc.org>
Fri, 11 Jun 2021 06:58:15 +0000 (16:58 +1000)
committerMark Andrews <marka@isc.org>
Tue, 20 Jul 2021 05:17:32 +0000 (15:17 +1000)
bin/nsupdate/nsupdate.c
lib/dns/zone.c

index dfe4721be7737005edfeef70916b090e5c1bc192..67fea4ed737a7dd79688c6ec8bcf3ce415c9f4df 100644 (file)
@@ -2445,6 +2445,10 @@ update_completed(isc_task_t *task, isc_event_t *event) {
                check_result(result, "dns_request_getresponse");
        }
 
+       if (answer->opcode != dns_opcode_update) {
+               fatal("invalid OPCODE in response to UPDATE request");
+       }
+
        if (answer->rcode != dns_rcode_noerror) {
                seenerror = true;
                if (!debugging) {
@@ -2651,6 +2655,10 @@ recvsoa(isc_task_t *task, isc_event_t *event) {
                show_message(stderr, rcvmsg, "Reply from SOA query:");
        }
 
+       if (rcvmsg->opcode != dns_opcode_query) {
+               fatal("invalid OPCODE in response to SOA query");
+       }
+
        if (rcvmsg->rcode != dns_rcode_noerror &&
            rcvmsg->rcode != dns_rcode_nxdomain) {
                fatal("response to SOA query was unsuccessful");
@@ -3124,6 +3132,10 @@ recvgss(isc_task_t *task, isc_event_t *event) {
                             "recvmsg reply from GSS-TSIG query");
        }
 
+       if (rcvmsg->opcode != dns_opcode_query) {
+               fatal("invalid OPCODE in response to GSS-TSIG query");
+       }
+
        if (rcvmsg->rcode == dns_rcode_formerr && !tried_other_gsstsig) {
                ddebug("recvgss trying %s GSS-TSIG",
                       use_win2k_gsstsig ? "Standard" : "Win2k");
index c8d0f74d8498eb76034f5532beddf344292f1310..76b07514d62280f48fb438328f376bf8292c8a66 100644 (file)
@@ -58,6 +58,7 @@
 #include <dns/name.h>
 #include <dns/nsec.h>
 #include <dns/nsec3.h>
+#include <dns/opcode.h>
 #include <dns/peer.h>
 #include <dns/private.h>
 #include <dns/rcode.h>
@@ -13181,6 +13182,23 @@ stub_glue_response_cb(isc_task_t *task, isc_event_t *event) {
                goto cleanup;
        }
 
+       /*
+        * Unexpected opcode.
+        */
+       if (msg->opcode != dns_opcode_query) {
+               char opcode[128];
+               isc_buffer_t rb;
+
+               isc_buffer_init(&rb, opcode, sizeof(opcode));
+               (void)dns_opcode_totext(msg->rcode, &rb);
+
+               dns_zone_log(zone, ISC_LOG_INFO,
+                            "refreshing stub: "
+                            "unexpected opcode (%.*s) from %s (source %s)",
+                            (int)rb.used, opcode, master, source);
+               goto cleanup;
+       }
+
        /*
         * Unexpected rcode.
         */
@@ -13593,6 +13611,23 @@ stub_callback(isc_task_t *task, isc_event_t *event) {
                goto next_master;
        }
 
+       /*
+        * Unexpected opcode.
+        */
+       if (msg->opcode != dns_opcode_query) {
+               char opcode[128];
+               isc_buffer_t rb;
+
+               isc_buffer_init(&rb, opcode, sizeof(opcode));
+               (void)dns_opcode_totext(msg->rcode, &rb);
+
+               dns_zone_log(zone, ISC_LOG_INFO,
+                            "refreshing stub: "
+                            "unexpected opcode (%.*s) from %s (source %s)",
+                            (int)rb.used, opcode, master, source);
+               goto next_master;
+       }
+
        /*
         * Unexpected rcode.
         */
@@ -13982,6 +14017,23 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
                goto next_master;
        }
 
+       /*
+        * Unexpected opcode.
+        */
+       if (msg->opcode != dns_opcode_query) {
+               char opcode[128];
+               isc_buffer_t rb;
+
+               isc_buffer_init(&rb, opcode, sizeof(opcode));
+               (void)dns_opcode_totext(msg->rcode, &rb);
+
+               dns_zone_log(zone, ISC_LOG_INFO,
+                            "refresh: "
+                            "unexpected opcode (%.*s) from %s (source %s)",
+                            (int)rb.used, opcode, master, source);
+               goto next_master;
+       }
+
        /*
         * Unexpected rcode.
         */
@@ -18221,6 +18273,23 @@ forward_callback(isc_task_t *task, isc_event_t *event) {
                goto next_master;
        }
 
+       /*
+        * Unexpected opcode.
+        */
+       if (msg->opcode != dns_opcode_update) {
+               char opcode[128];
+               isc_buffer_t rb;
+
+               isc_buffer_init(&rb, opcode, sizeof(opcode));
+               (void)dns_opcode_totext(msg->rcode, &rb);
+
+               dns_zone_log(zone, ISC_LOG_INFO,
+                            "forwarding dynamic update: "
+                            "unexpected opcode (%.*s) from %s",
+                            (int)rb.used, opcode, master);
+               goto next_master;
+       }
+
        switch (msg->rcode) {
        /*
         * Pass these rcodes back to client.