Hi!

While testing 7.0 packages I got an nmap segfault.  It has been fixed upstream in their github, but I don't know if it's part of any release yet.

However their fix may be incomplete as there are other opportunities for a negative buffer overflow in nmap_dns.cc, at least without knowing all callers of the ptrToIp method.

I attach a patch that works for me (tm) as well as a patch to add a debug package for nmap, which was needed for me to debug this issue.

Even if its too late for 7.0, at least the segfault fix might make 7.0-stable package, I reckon.

The fault is indeterministic, and triggered by a PTR name being aligned at the beginning of a page immediately preceded by an unmapped page.  The case which triggers it fairly often for me was just a nmap of a single TCP port over some seven or so /24-networks.

/Niklas
commit 550c8a099e5eb1189e26f8868927c7b5cba950f2
Author: niklas <nik...@appli.se>
Date:   Tue Sep 28 14:49:55 2021 +0200

    Avoid careless dereferences outside the domain name buffer

diff --git a/net/nmap/patches/patch-nmap_dns_cc b/net/nmap/patches/patch-nmap_dns_cc
new file mode 100644
index 00000000000..45e74a3e735
--- /dev/null
+++ b/net/nmap/patches/patch-nmap_dns_cc
@@ -0,0 +1,42 @@
+$OpenBSD$
+
+Avoid careless dereferences outside the domain name buffer.
+
+Index: nmap_dns.cc
+--- nmap_dns.cc.orig
++++ nmap_dns.cc
+@@ -1352,7 +1352,7 @@ bool DNS::Factory::ptrToIp(const std::string &ptr, soc
+   memset(&ip, 0, sizeof(sockaddr_storage));
+ 
+   // Check whether the name ends with the IPv4 PTR domain
+-  if (NULL != (p = strcasestr(cptr + ptr.length() + 1 - sizeof(C_IPV4_PTR_DOMAIN), C_IPV4_PTR_DOMAIN)))
++  if (ptr.length() >= sizeof(C_IPV4_PTR_DOMAIN) - 1 && NULL != (p = strcasestr(cptr + ptr.length() + 1 - sizeof(C_IPV4_PTR_DOMAIN), C_IPV4_PTR_DOMAIN)))
+   {
+     struct sockaddr_in *ip4 = (struct sockaddr_in *)&ip;
+     u8 place_value[] = {1, 10, 100};
+@@ -1361,7 +1361,7 @@ bool DNS::Factory::ptrToIp(const std::string &ptr, soc
+     size_t i = 0;
+ 
+     p--;
+-    while (i < sizeof(ip4->sin_addr.s_addr))
++    while (p >= cptr && i < sizeof(ip4->sin_addr.s_addr))
+     {
+       if (*p == '.')
+       {
+@@ -1387,14 +1387,14 @@ bool DNS::Factory::ptrToIp(const std::string &ptr, soc
+     ip.ss_family = AF_INET;
+   }
+   // If not, check IPv6
+-  else if (NULL != (p = strcasestr(cptr + ptr.length() + 1 - sizeof(C_IPV6_PTR_DOMAIN), C_IPV6_PTR_DOMAIN)))
++  else if (ptr.length() >= sizeof(C_IPV6_PTR_DOMAIN) - 1 && NULL != (p = strcasestr(cptr + ptr.length() + 1 - sizeof(C_IPV6_PTR_DOMAIN), C_IPV6_PTR_DOMAIN)))
+   {
+     struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)&ip;
+     u8 alt = 0;
+     size_t i=0;
+ 
+     p--;
+-    while (i < sizeof(ip6->sin6_addr.s6_addr))
++    while (p >= cptr && i < sizeof(ip6->sin6_addr.s6_addr))
+     {
+       if (*p == '.')
+       {
commit f2aafb4430c0150d70926e3277d0d816805111cb
Author: niklas <nik...@appli.se>
Date:   Tue Sep 28 14:49:06 2021 +0200

    Make debug packages

diff --git a/net/nmap/Makefile b/net/nmap/Makefile
index ff8db3d7594..c1752ffef46 100644
--- a/net/nmap/Makefile
+++ b/net/nmap/Makefile
@@ -33,6 +33,7 @@ MODULES=	lang/python \
 		lang/lua
 MODPY_VERSION=	${MODPY_DEFAULT_VERSION_2}
 
+DEBUG_PACKAGES= ${BUILD_PACKAGES}
 CONFIGURE_STYLE=autoconf
 AUTOCONF_VERSION=2.69
 

Reply via email to