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