Wednesday, September 29, 2021

nmap segfault fix

commit 550c8a099e5eb1189e26f8868927c7b5cba950f2
Author: niklas <niklas@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 <niklas@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

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

No comments:

Post a Comment