85d510
From c2bc14ff30c349b52b5f84cef6b73061a0394143 Mon Sep 17 00:00:00 2001
85d510
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
85d510
Date: Thu, 11 Apr 2019 18:17:16 +0200
85d510
Subject: [PATCH] inet_aton: Use getaddrinfo() if possible
85d510
MIME-Version: 1.0
85d510
Content-Type: text/plain; charset=UTF-8
85d510
Content-Transfer-Encoding: 8bit
85d510
85d510
Socket::inet_aton() used gethostbyname() to process arguments that are
85d510
not an IP addres. However, gethostbyname() is not thread-safe and when
85d510
called from multiple threads a bogus value can be returned.
85d510
85d510
This patch does add any new test because a basic inet_aton() usage is
85d510
already covered and because reproducing the thread failure would
85d510
require flodding DNS servers with thousounds of request.
85d510
85d510
<https://rt.perl.org/Public/Bug/Display.html?id=97860>
85d510
<https://bugzilla.redhat.com/show_bug.cgi?id=1693293>
85d510
85d510
Signed-off-by: Petr Písař <ppisar@redhat.com>
85d510
---
85d510
 Socket.xs | 15 +++++++++++++++
85d510
 1 file changed, 15 insertions(+)
85d510
85d510
diff --git a/Socket.xs b/Socket.xs
85d510
index 753cd09..6f6ced8 100644
85d510
--- a/Socket.xs
85d510
+++ b/Socket.xs
85d510
@@ -584,6 +584,19 @@ inet_aton(host)
85d510
 	char *	host
85d510
 	CODE:
85d510
 	{
85d510
+#ifdef HAS_GETADDRINFO
85d510
+	struct addrinfo *res;
85d510
+	struct addrinfo hints = {0,};
85d510
+	hints.ai_family = AF_INET;
85d510
+	if (!getaddrinfo(host, NULL, &hints, &res)) {
85d510
+	    ST(0) = sv_2mortal(newSVpvn(
85d510
+		(char *)&(((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr),
85d510
+		4
85d510
+	));
85d510
+	freeaddrinfo(res);
85d510
+	XSRETURN(1);
85d510
+    }
85d510
+#else
85d510
 	struct in_addr ip_address;
85d510
 	struct hostent * phe;
85d510
 
85d510
@@ -592,11 +605,13 @@ inet_aton(host)
85d510
 		XSRETURN(1);
85d510
 	}
85d510
 
85d510
+	/* gethostbyname is not thread-safe */
85d510
 	phe = gethostbyname(host);
85d510
 	if (phe && phe->h_addrtype == AF_INET && phe->h_length == 4) {
85d510
 		ST(0) = sv_2mortal(newSVpvn((char *)phe->h_addr, phe->h_length));
85d510
 		XSRETURN(1);
85d510
 	}
85d510
+#endif
85d510
 
85d510
 	XSRETURN_UNDEF;
85d510
 	}
85d510
-- 
85d510
2.20.1
85d510