This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[RFC PATCH] getaddrinfo: Force name resolution for AI_CANONNAME [BZ# 24182]
- From: "Heitor R. Alves de Siqueira" <halves at canonical dot com>
- To: libc-alpha at sourceware dot org
- Cc: Florian Weimer <fweimer at redhat dot com>, Dan Streetman <dan dot streetman at canonical dot com>, "Heitor R. Alves de Siqueira" <halves at canonical dot com>
- Date: Fri, 8 Feb 2019 15:52:45 -0200
- Subject: [RFC PATCH] getaddrinfo: Force name resolution for AI_CANONNAME [BZ# 24182]
When getaddrinfo() is called with a numeric nodename argument (e.g.
67882190), we should try name resolution if AI_CANONNAME is set. RFC
1123 allows digits-only hostnames, but inet_aton_exact() can interpret
these as valid IPv4 addresses in a 32-bit number form. This behaviour
causes the internal gaih_inet() call to think a numeric hostname is a
valid IPv4 address and skip name resolution.
One can reproduce this by following these steps:
1) Append numeric hostname records to /etc/hosts:
$ head -n2 /etc/hosts
127.0.0.1 localhost
127.0.0.1 1234.example.com 1234
2) Change local hostname to the numeric record:
$ sudo hostname 1234
3) Call `hostname -f` (output should be '1234.example.com'):
$ hostname -f
1234
This patch forces name resolution if the AI_CANONNAME flag is set. Even
if inet_aton_exact() identifies the input name as being a valid IPv4
address, we will try name resolution in case it's a valid hostname. If
no hostname is found after resolution, the input name is still copied
to the ai_canonname field.
The patch was tested on amd64, and the glibc test suite showed no
regressions. Further use case tests showed that current behaviour is
not modified w.r.t. IPv4 addresses.
---
This is a tentative patch suggestion for BZ# 24182. The general idea is
already being discussed there, but I would like some more thoughts on
the patch specifically, if possible. Likely there are many ways to
tackle this and I'm unsure which would be best suited. Thanks!
Heitor
sysdeps/posix/getaddrinfo.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index aa054b620f2a..fa9e2d6ad3b1 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -505,9 +505,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
result = -EAI_ADDRFAMILY;
goto free_and_return;
}
-
- if (req->ai_flags & AI_CANONNAME)
- canon = name;
}
else if (at->family == AF_UNSPEC)
{
@@ -548,7 +545,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
}
}
- if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
+ if ((at->family == AF_UNSPEC || (req->ai_flags & AI_CANONNAME))
+ && (req->ai_flags & AI_NUMERICHOST) == 0)
{
struct gaih_addrtuple **pat = &at;
int no_data = 0;
--
2.17.1