aboutsummaryrefslogtreecommitdiff
path: root/inet/getnameinfo.c
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2018-05-23 15:26:19 +0200
committerFlorian Weimer <fweimer@redhat.com>2018-05-23 15:27:24 +0200
commit7f9f1ecb710eac4d65bb02785ddf288cac098323 (patch)
treeb93086996bfb5edf0221b895128ef5a6e709dead /inet/getnameinfo.c
parent5f7b841d3aebdccc2baed27cb4b22ddb08cd7c0c (diff)
downloadglibc-7f9f1ecb710eac4d65bb02785ddf288cac098323.zip
glibc-7f9f1ecb710eac4d65bb02785ddf288cac098323.tar.gz
glibc-7f9f1ecb710eac4d65bb02785ddf288cac098323.tar.bz2
Switch IDNA implementation to libidn2 [BZ #19728] [BZ #19729] [BZ #22247]
This provides an implementation of the IDNA2008 standard and fixes CVE-2016-6261, CVE-2016-6263, CVE-2017-14062.
Diffstat (limited to 'inet/getnameinfo.c')
-rw-r--r--inet/getnameinfo.c56
1 files changed, 20 insertions, 36 deletions
diff --git a/inet/getnameinfo.c b/inet/getnameinfo.c
index a20d20b..5d4978e 100644
--- a/inet/getnameinfo.c
+++ b/inet/getnameinfo.c
@@ -71,10 +71,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sys/utsname.h>
#include <libc-lock.h>
#include <scratch_buffer.h>
-
-#ifdef HAVE_LIBIDN
-# include <idna.h>
-#endif
+#include <net-internal.h>
#ifndef min
# define min(x,y) (((x) > (y)) ? (y) : (x))
@@ -82,6 +79,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
libc_freeres_ptr (static char *domain);
+/* Former NI_IDN_ALLOW_UNASSIGNED, NI_IDN_USE_STD3_ASCII_RULES flags,
+ now ignored. */
+#define DEPRECATED_NI_IDN 192
static char *
nrl_domainname (void)
@@ -285,41 +285,28 @@ gni_host_inet_name (struct scratch_buffer *tmpbuf,
/* Terminate the string after the prefix. */
*c = '\0';
-#ifdef HAVE_LIBIDN
/* If requested, convert from the IDN format. */
- if (flags & NI_IDN)
+ bool do_idn = flags & NI_IDN;
+ char *h_name;
+ if (do_idn)
{
- int idn_flags = 0;
- if (flags & NI_IDN_ALLOW_UNASSIGNED)
- idn_flags |= IDNA_ALLOW_UNASSIGNED;
- if (flags & NI_IDN_USE_STD3_ASCII_RULES)
- idn_flags |= IDNA_USE_STD3_ASCII_RULES;
-
- char *out;
- int rc = __idna_to_unicode_lzlz (h->h_name, &out,
- idn_flags);
- if (rc != IDNA_SUCCESS)
- {
- if (rc == IDNA_MALLOC_ERROR)
- return EAI_MEMORY;
- if (rc == IDNA_DLOPEN_ERROR)
- return EAI_SYSTEM;
- return EAI_IDN_ENCODE;
- }
-
- if (out != h->h_name)
- {
- h->h_name = strdupa (out);
- free (out);
- }
+ int rc = __idna_from_dns_encoding (h->h_name, &h_name);
+ if (rc == EAI_IDN_ENCODE)
+ /* Use the punycode name as a fallback. */
+ do_idn = false;
+ else if (rc != 0)
+ return rc;
}
-#endif
+ if (!do_idn)
+ h_name = h->h_name;
- size_t len = strlen (h->h_name) + 1;
+ size_t len = strlen (h_name) + 1;
if (len > hostlen)
return EAI_OVERFLOW;
+ memcpy (host, h_name, len);
- memcpy (host, h->h_name, len);
+ if (do_idn)
+ free (h_name);
return 0;
}
@@ -501,10 +488,7 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
int flags)
{
if (flags & ~(NI_NUMERICHOST|NI_NUMERICSERV|NI_NOFQDN|NI_NAMEREQD|NI_DGRAM
-#ifdef HAVE_LIBIDN
- |NI_IDN|NI_IDN_ALLOW_UNASSIGNED|NI_IDN_USE_STD3_ASCII_RULES
-#endif
- ))
+ |NI_IDN|DEPRECATED_NI_IDN))
return EAI_BADFLAGS;
if (sa == NULL || addrlen < sizeof (sa_family_t))