This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]