From f752603604c24098f47db1ec6e114e4149c44d47 Mon Sep 17 00:00:00 2001 From: dmiller Date: Tue, 7 Apr 2026 13:51:07 +0000 Subject: [PATCH] Fix 1-byte read overrun --- CHANGELOG | 3 +++ nmap_dns.cc | 4 +++- tests/nmap_dns_test.cc | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index d13edfd83..a7276394b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ #Nmap Changelog ($Id$); -*-text-*- +o Fix a 1-byte overrun (read) while reading certain crafted DNS labels, + reported by Peter Parker. [Daniel Miller] + o [NSE][GH#3317] Function url.build_path was mangling special characters in URL path segments. [nnposter] diff --git a/nmap_dns.cc b/nmap_dns.cc index 56bdafb8b..d3731d9fc 100644 --- a/nmap_dns.cc +++ b/nmap_dns.cc @@ -1886,9 +1886,10 @@ size_t DNS::Factory::parseDomainName(std::string &name, const u8 *buf, size_t of size_t tmp = 0; size_t max_offset = offset; size_t curr_offset = offset; + u8 label_length = 0; name.clear(); - while(u8 label_length = buf[curr_offset]) + while(curr_offset < maxlen && 0 != (label_length = buf[curr_offset])) { if((label_length & COMPRESSED_NAME) == COMPRESSED_NAME) { @@ -1938,6 +1939,7 @@ size_t DNS::Factory::parseDomainName(std::string &name, const u8 *buf, size_t of } } + DNS_CHECK_UPPER_BOUND(curr_offset, maxlen - 1); if (max_offset == curr_offset && buf[curr_offset] == '\0') { max_offset++; } diff --git a/tests/nmap_dns_test.cc b/tests/nmap_dns_test.cc index 359237490..102911a52 100644 --- a/tests/nmap_dns_test.cc +++ b/tests/nmap_dns_test.cc @@ -197,6 +197,24 @@ o.debugging = 1; DNS::PTR_Record * r = static_cast(a->record); TEST_INCR(r->value == target, ret); + const u8 inval_answer[] = { + 0x12, 0x34, // ID + 0x81, 0x80, // Flags + 0x00, 0x01, // Questions count + 0x00, 0x01, // Answers RRs count + 0x00, 0x00, // Authorities RRs count + 0x00, 0x00, // Additionals RRs count + 0x06, // Label length <-- [12] + 0x73, 0x63, 0x61, 0x6e, 0x6d, 0x65, // "scanme" + 0x04, // Label length + 0x6e, 0x6d, 0x61, 0x70, // "nmap" + 0x03, // Label length + 0x6f, 0x72, 0x67, // "org" + }; // Deliberately ends before final empty label + plen = p.parseFromBuffer(inval_answer, sizeof(inval_answer)); + TEST_INCR(plen == 0, ret); + + if(ret) std::cout << "Testing nmap_dns finished with errors" << std::endl; else std::cout << "Testing nmap_dns finished without errors" << std::endl;