- To: libc-gnats at gnu dot org, gnats-admin at gnu dot org
- Subject: libc/2181: segmentation fault in getaddrinfo()
- From: sw at network-analysis dot ltd dot uk
- Date: Fri, 06 Apr 2001 07:13:52 -0400
- Reply-To: sw at network-analysis dot ltd dot uk
- Xref: gee.suse.de mail.gnats-libc-bugs:5907
>Number: 2181
>Category: libc
>Synopsis: segmentation fault in getaddrinfo()
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: libc-gnats
>State: open
>Quarter:
>Keywords:
>Class: sw-bug
>Submitter-Id: gnatsweb
>Arrival-Date: Fri Apr 06 07:13:52 -0400 2001
>Cases:
>Originator: Sak Wathanasin
>Release: glibc 2.2.1, 2.2.2
>Organization:
Network Analysis Ltd
>Environment:
Host type: i386-redhat-linux-gnu
System: Linux 2.2.18 #16 Thu Jan 25 10:55:25 GMT 2001 i686
>Description:
If called with a "hints" struct where the protocol type
is not specified, getaddrinfo() gets a segment violation. In
.../sysdeps/posix/getaddrinfo.c, the routine gaih_inet has
a for loop (line 417)
for (++tp; tp->name != NULL; ++tp) {
...
}
The exit test is wrong because the field "name" is a char[]
that is embedded inside *tp (type = struct gaih_typeproto),
and will never be NULL.
In case you're wondering, bind 9.1.x uses code that is like
the test code below, and doing, e.g., "dig @foo" will result
in a seg violation.
>How-To-Repeat:
/* compile with
cc -g -o test test.c
and run eg
./test localhost
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
main (int argc, char** argv)
{
struct in_addr in4;
struct addrinfo *res = NULL,
hints;
int result = 0;
char buf[101] = {0};
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_INET;
result = getaddrinfo(argv[1], NULL, &hints, &res);
if (result == 0) {
/* succeeded */
inet_ntop(AF_INET, &(((struct sockaddr_in *)(res->ai_addr))->sin_addr), buf, INET_ADDRSTRLEN);
printf("Addr = %s\n", buf);
}
else {
printf("Lookup failed\n");
}
}
>Fix:
--- sysdeps/posix/getaddrinfo.c.gai Wed Jan 24 08:57:10 2001
+++ sysdeps/posix/getaddrinfo.c Thu Apr 5 11:43:38 2001
@@ -414,7 +414,7 @@
/* Neither socket type nor protocol is set. Return all socket types
we know about. */
struct gaih_servtuple **lastp = &st;
- for (++tp; tp->name != NULL; ++tp)
+ for (++tp; tp->name[0] != '\0'; ++tp)
{
struct gaih_servtuple *newp;
>Unformatted: