This is the mail archive of the
glibc-bugs@sources.redhat.com
mailing list for the glibc project.
[Bug libc/304] AI_CANONNAME in getaddrinfo(): name is an address; result sorting
- From: "a dot guru at sympatico dot ca" <sourceware-bugzilla at sources dot redhat dot com>
- To: glibc-bugs at sources dot redhat dot com
- Date: 17 Aug 2004 04:20:00 -0000
- Subject: [Bug libc/304] AI_CANONNAME in getaddrinfo(): name is an address; result sorting
- References: <20040806075934.304.a.guru@sympatico.ca>
- Reply-to: sourceware-bugzilla at sources dot redhat dot com
------- Additional Comments From a dot guru at sympatico dot ca 2004-08-17 04:19 -------
This comment replaces my previous ones.
All quotes are from
<http://www.opengroup.org/onlinepubs/009695399/functions/getaddrinfo.html>.
All issues relative to cvs version 1.67 of getaddrinfo.c, which is
the latest at the time of writing.
Issues:
-- "The freeaddrinfo() function shall support the freeing of
arbitrary sublists of an addrinfo list originally returned
by getaddrinfo()."
For example:
struct addrinfo hints = { .ai_flags = AI_CANNONNAME };
rc = getaddrinfo(nodename, servname, &hints, &res);
freeaddrinfo(res->ai_next);
printf("%s\n", res->ai_canonname);
This is legal (except for the error and non-NULL checkings).
The problem is that the way ai_canonname is allocated
(in the same malloc() as the original struct addrinfo
itself), the first struct addrinfo after reordering may
be other than the original one and now contains a pointer
to memory in another malloc(), that of the original one.
By the time the printf() above is executed, we may
dereference freed memory.
The solution is to either allocate ai_canonname separately
(which is what I have done) or realloc() the new first
struct addrinfo if it is not the original one and store a
copy of ai_canonname in it.
In the new patch, notice earlier use of local_hints, removal
of "const" in prototypes, usage of req->ai_canonname, usage
of strdup(), and usage of free(... ai_canonname).
-- "In this hints structure every member other than ai_flags,
ai_family, ai_socktype, and ai_protocol shall be set to zero
or a null pointer."
"If hints is a null pointer, the behavior shall be as if it
referred to a structure containing the value zero for the
ai_flags, ai_socktype, and ai_protocol fields, and AF_UNSPEC
for the ai_family field."
I removed all fields which should be zero in the
initializer of default_hints which will accomplish
just that. No more AI_DEFAULT.
-- "If the AI_CANONNAME flag is specified and the nodename argument
is not null..."
"A numeric host address string is not a ``name'', and thus
does not have a ``canonical name'' form; no address to host
name translation is performed. See below for handling of
the case where a canonical name cannot be obtained."
"... if the canonical name is not available, then ai_canonname
shall refer to the nodename argument or a string with the
same contents."
Here, the nodename argument should be an unmodified
"name", not some transformation of it by libidn.
I've called the transformed version "iname" and used
it where appropriate when HAVE_LIBIDN.
-- The ai_canonname field should be the result of following a
CNAME RR chain (if any) to the _owner_ of an AAAA or A record,
not the result of waiting to follow those address records
(there may be many) then following back PTR RRs (which may
be one of many or not exist at all for each address record).
See original bug description for more details.
I didn't remove the code that uses __gethostbyaddr_r(),
just in case ai_canonname has not be found by then,
but maybe it should just be gone altogether.
-- Each and every call to resolving functions (through NSS or
direct) may result in network traffic or at least file
manipulations. (Assume there is no cache, which is a
possibility.) We should always avoid calling such a function
if the result it can provide could have been extracted from
a previous call.
I tried to set canon as early as possible and only if
necessary.
-- Weird returned struct hostent are possible.
Thus the (h && h->h_name && h->h_name[0]) checks.
--
http://sources.redhat.com/bugzilla/show_bug.cgi?id=304
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.