From ed4e00713fa52d361b2bbf0eeae80a6da7323255 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Fri, 11 Jun 2021 16:58:15 +1000 Subject: [PATCH] Check opcode of messages returned by dns_request_getresponse --- bin/nsupdate/nsupdate.c | 12 +++++++ lib/dns/zone.c | 69 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index dfe4721be7..67fea4ed73 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -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"); diff --git a/lib/dns/zone.c b/lib/dns/zone.c index c8d0f74d84..76b07514d6 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -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.